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;
56 typedef struct VideoRendererImpl
58 const IBaseFilterVtbl * lpVtbl;
59 const IBasicVideoVtbl * IBasicVideo_vtbl;
60 const IVideoWindowVtbl * IVideoWindow_vtbl;
61 const IUnknownVtbl * IInner_vtbl;
64 CRITICAL_SECTION csFilter;
66 REFERENCE_TIME rtStreamStart;
67 IReferenceClock * pClock;
68 FILTER_INFO filterInfo;
90 REFERENCE_TIME rtLastStop;
91 MediaSeekingImpl mediaSeeking;
94 /* During pause we can hold a single sample, for use in GetCurrentImage */
95 IMediaSample *sample_held;
98 static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
100 VideoRendererImpl* pVideoRenderer = (VideoRendererImpl*)GetWindowLongPtrW(hwnd, 0);
101 LPRECT lprect = (LPRECT)lParam;
103 if (pVideoRenderer && pVideoRenderer->hWndMsgDrain)
109 case WM_LBUTTONDBLCLK:
112 case WM_MBUTTONDBLCLK:
115 case WM_MOUSEACTIVATE:
117 case WM_NCLBUTTONDBLCLK:
118 case WM_NCLBUTTONDOWN:
120 case WM_NCMBUTTONDBLCLK:
121 case WM_NCMBUTTONDOWN:
124 case WM_NCRBUTTONDBLCLK:
125 case WM_NCRBUTTONDOWN:
127 case WM_RBUTTONDBLCLK:
130 PostMessageA(pVideoRenderer->hWndMsgDrain, uMsg, wParam, lParam);
140 /* TRACE("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); */
141 SetWindowPos(hwnd, NULL, lprect->left, lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top, SWP_NOZORDER);
142 GetClientRect(hwnd, &pVideoRenderer->DestRect);
143 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
144 pVideoRenderer->DestRect.left,
145 pVideoRenderer->DestRect.top,
146 pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left,
147 pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top);
150 TRACE("WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam));
151 GetClientRect(hwnd, &pVideoRenderer->DestRect);
152 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
153 pVideoRenderer->DestRect.left,
154 pVideoRenderer->DestRect.top,
155 pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left,
156 pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top);
159 return DefWindowProcA(hwnd, uMsg, wParam, lParam);
164 static BOOL CreateRenderingWindow(VideoRendererImpl* This)
168 TRACE("(%p)->()\n", This);
171 winclass.lpfnWndProc = VideoWndProcA;
172 winclass.cbClsExtra = 0;
173 winclass.cbWndExtra = sizeof(VideoRendererImpl*);
174 winclass.hInstance = NULL;
175 winclass.hIcon = NULL;
176 winclass.hCursor = NULL;
177 winclass.hbrBackground = GetStockObject(BLACK_BRUSH);
178 winclass.lpszMenuName = NULL;
179 winclass.lpszClassName = "Wine ActiveMovie Class";
181 if (!wnd_class_registered)
183 if (!RegisterClassA(&winclass))
185 ERR("Unable to register window %u\n", GetLastError());
188 wnd_class_registered = TRUE;
191 This->hWnd = CreateWindowExA(0, "Wine ActiveMovie Class", "Wine ActiveMovie Window", WS_SIZEBOX,
192 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
197 ERR("Unable to create window\n");
201 SetWindowLongPtrW(This->hWnd, 0, (LONG_PTR)This);
206 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
208 VideoRendererImpl* This = lpParameter;
212 TRACE("Starting message loop\n");
214 if (!CreateRenderingWindow(This))
216 This->ThreadResult = FALSE;
217 SetEvent(This->hEvent);
221 This->ThreadResult = TRUE;
222 SetEvent(This->hEvent);
224 while ((fGotMessage = GetMessageA(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
226 TranslateMessage(&msg);
227 DispatchMessageA(&msg);
230 TRACE("End of message loop\n");
235 static BOOL CreateRenderingSubsystem(VideoRendererImpl* This)
237 This->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
241 This->hThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->ThreadID);
244 CloseHandle(This->hEvent);
248 WaitForSingleObject(This->hEvent, INFINITE);
250 if (!This->ThreadResult)
252 CloseHandle(This->hEvent);
253 CloseHandle(This->hThread);
260 static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
266 BITMAPINFOHEADER *bmiHeader;
268 TRACE("(%p)->(%p, %d)\n", This, data, size);
270 sdesc.dwSize = sizeof(sdesc);
271 hr = IPin_ConnectionMediaType((IPin *)This->pInputPin, &amt);
273 ERR("Unable to retrieve media type\n");
277 if (IsEqualIID(&amt.formattype, &FORMAT_VideoInfo))
279 bmiHeader = &((VIDEOINFOHEADER *)amt.pbFormat)->bmiHeader;
281 else if (IsEqualIID(&amt.formattype, &FORMAT_VideoInfo2))
283 bmiHeader = &((VIDEOINFOHEADER2 *)amt.pbFormat)->bmiHeader;
287 FIXME("Unknown type %s\n", debugstr_guid(&amt.subtype));
288 return VFW_E_RUNTIME_ERROR;
291 TRACE("biSize = %d\n", bmiHeader->biSize);
292 TRACE("biWidth = %d\n", bmiHeader->biWidth);
293 TRACE("biHeight = %d\n", bmiHeader->biHeight);
294 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
295 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
296 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
297 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
301 if (!This->WindowPos.right || !This->WindowPos.top)
303 DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE);
304 DWORD style_ex = GetWindowLongW(This->hWnd, GWL_EXSTYLE);
306 if (!This->WindowPos.right)
308 This->WindowPos.left = This->SourceRect.left;
309 This->WindowPos.right = This->SourceRect.right;
311 if (!This->WindowPos.bottom)
313 This->WindowPos.top = This->SourceRect.top;
314 This->WindowPos.bottom = This->SourceRect.bottom;
317 AdjustWindowRectEx(&This->WindowPos, style, TRUE, style_ex);
319 TRACE("WindowPos: %d %d %d %d\n", This->WindowPos.left, This->WindowPos.top, This->WindowPos.right, This->WindowPos.bottom);
320 SetWindowPos(This->hWnd, NULL,
321 This->WindowPos.left,
323 This->WindowPos.right - This->WindowPos.left,
324 This->WindowPos.bottom - This->WindowPos.top,
325 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
327 GetClientRect(This->hWnd, &This->DestRect);
330 This->DestRect = This->WindowPos;
334 hDC = GetDC(This->hWnd);
337 ERR("Cannot get DC from window!\n");
341 TRACE("Src Rect: %d %d %d %d\n", This->SourceRect.left, This->SourceRect.top, This->SourceRect.right, This->SourceRect.bottom);
342 TRACE("Dst Rect: %d %d %d %d\n", This->DestRect.left, This->DestRect.top, This->DestRect.right, This->DestRect.bottom);
344 StretchDIBits(hDC, This->DestRect.left, This->DestRect.top, This->DestRect.right -This->DestRect.left,
345 This->DestRect.bottom - This->DestRect.top, This->SourceRect.left, This->SourceRect.top,
346 This->SourceRect.right - This->SourceRect.left, This->SourceRect.bottom - This->SourceRect.top,
347 data, (BITMAPINFO *)bmiHeader, DIB_RGB_COLORS, SRCCOPY);
349 ReleaseDC(This->hWnd, hDC);
351 ShowWindow(This->hWnd, SW_SHOW);
356 static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
358 VideoRendererImpl *This = iface;
359 LPBYTE pbSrcStream = NULL;
360 LONG cbSrcStream = 0;
361 REFERENCE_TIME tStart, tStop;
364 TRACE("(%p)->(%p)\n", iface, pSample);
366 EnterCriticalSection(&This->csFilter);
368 if (This->pInputPin->flushing || This->pInputPin->end_of_stream)
370 LeaveCriticalSection(&This->csFilter);
374 if (This->state == State_Stopped)
376 LeaveCriticalSection(&This->csFilter);
377 return VFW_E_WRONG_STATE;
380 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
382 ERR("Cannot get sample time (%x)\n", hr);
384 if (This->rtLastStop != tStart && This->state == State_Running)
387 delta = tStart - This->rtLastStop;
388 if ((delta < -100000 || delta > 100000) &&
389 IMediaSample_IsDiscontinuity(pSample) == S_FALSE)
390 ERR("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n",
391 (DWORD)(This->rtLastStop / 10000000),
392 (DWORD)((This->rtLastStop / 10000)%1000),
393 (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000));
394 This->rtLastStop = tStart;
397 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
398 if (IMediaSample_IsPreroll(pSample) == S_OK)
400 This->rtLastStop = tStop;
401 LeaveCriticalSection(&This->csFilter);
405 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
408 ERR("Cannot get pointer to sample data (%x)\n", hr);
409 LeaveCriticalSection(&This->csFilter);
413 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
415 TRACE("val %p %d\n", pbSrcStream, cbSrcStream);
417 #if 0 /* For debugging purpose */
420 for(i = 0; i < cbSrcStream; i++)
422 if ((i!=0) && !(i%16))
424 TRACE("%02x ", pbSrcStream[i]);
430 SetEvent(This->hEvent);
431 if (This->state == State_Paused)
433 This->sample_held = pSample;
434 LeaveCriticalSection(&This->csFilter);
435 WaitForSingleObject(This->blocked, INFINITE);
436 EnterCriticalSection(&This->csFilter);
437 This->sample_held = NULL;
438 if (This->state == State_Paused)
441 LeaveCriticalSection(&This->csFilter);
444 if (This->state == State_Stopped)
446 LeaveCriticalSection(&This->csFilter);
447 return VFW_E_WRONG_STATE;
451 if (This->pClock && This->state == State_Running)
453 REFERENCE_TIME time, trefstart, trefstop;
456 /* Perhaps I <SHOULD> use the reference clock AdviseTime function here
457 * I'm not going to! When I tried, it seemed to generate lag and
458 * it caused instability.
460 IReferenceClock_GetTime(This->pClock, &time);
462 trefstart = This->rtStreamStart;
463 trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->rtStreamStart;
464 delta = (LONG)((trefstart-time)/10000);
465 This->rtStreamStart = trefstop;
466 This->rtLastStop = tStop;
470 TRACE("Sleeping for %u ms\n", delta);
473 else if (time > trefstop)
475 TRACE("Dropping sample: Time: %u.%03u ms trefstop: %u.%03u ms!\n",
476 (DWORD)(time / 10000000), (DWORD)((time / 10000)%1000),
477 (DWORD)(trefstop / 10000000), (DWORD)((trefstop / 10000)%1000) );
478 This->rtLastStop = tStop;
479 LeaveCriticalSection(&This->csFilter);
483 This->rtLastStop = tStop;
485 VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
487 LeaveCriticalSection(&This->csFilter);
491 static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
493 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video))
496 if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32) ||
497 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24) ||
498 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565) ||
499 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8))
501 VideoRendererImpl* This = iface;
504 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
506 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
507 This->SourceRect.left = 0;
508 This->SourceRect.top = 0;
509 This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth;
510 height = format->bmiHeader.biHeight;
512 This->SourceRect.bottom = This->VideoHeight = -height;
514 This->SourceRect.bottom = This->VideoHeight = height;
516 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
518 VIDEOINFOHEADER2 *format2 = (VIDEOINFOHEADER2 *)pmt->pbFormat;
520 This->SourceRect.left = 0;
521 This->SourceRect.top = 0;
522 This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth;
523 height = format2->bmiHeader.biHeight;
525 This->SourceRect.bottom = This->VideoHeight = -height;
527 This->SourceRect.bottom = This->VideoHeight = height;
531 WARN("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
539 static inline VideoRendererImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
541 return (VideoRendererImpl *)((char*)iface - FIELD_OFFSET(VideoRendererImpl, mediaSeeking.lpVtbl));
544 static HRESULT WINAPI VideoRendererImpl_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv)
546 VideoRendererImpl *This = impl_from_IMediaSeeking(iface);
548 return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
551 static ULONG WINAPI VideoRendererImpl_Seeking_AddRef(IMediaSeeking * iface)
553 VideoRendererImpl *This = impl_from_IMediaSeeking(iface);
555 return IUnknown_AddRef((IUnknown *)This);
558 static ULONG WINAPI VideoRendererImpl_Seeking_Release(IMediaSeeking * iface)
560 VideoRendererImpl *This = impl_from_IMediaSeeking(iface);
562 return IUnknown_Release((IUnknown *)This);
565 static const IMediaSeekingVtbl VideoRendererImpl_Seeking_Vtbl =
567 VideoRendererImpl_Seeking_QueryInterface,
568 VideoRendererImpl_Seeking_AddRef,
569 VideoRendererImpl_Seeking_Release,
570 MediaSeekingImpl_GetCapabilities,
571 MediaSeekingImpl_CheckCapabilities,
572 MediaSeekingImpl_IsFormatSupported,
573 MediaSeekingImpl_QueryPreferredFormat,
574 MediaSeekingImpl_GetTimeFormat,
575 MediaSeekingImpl_IsUsingTimeFormat,
576 MediaSeekingImpl_SetTimeFormat,
577 MediaSeekingImpl_GetDuration,
578 MediaSeekingImpl_GetStopPosition,
579 MediaSeekingImpl_GetCurrentPosition,
580 MediaSeekingImpl_ConvertTimeFormat,
581 MediaSeekingImpl_SetPositions,
582 MediaSeekingImpl_GetPositions,
583 MediaSeekingImpl_GetAvailable,
584 MediaSeekingImpl_SetRate,
585 MediaSeekingImpl_GetRate,
586 MediaSeekingImpl_GetPreroll
589 static HRESULT VideoRendererImpl_Change(IBaseFilter *iface)
591 TRACE("(%p)->()\n", iface);
595 HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
599 VideoRendererImpl * pVideoRenderer;
601 TRACE("(%p, %p)\n", pUnkOuter, ppv);
605 pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl));
606 pVideoRenderer->pUnkOuter = pUnkOuter;
607 pVideoRenderer->bUnkOuterValid = FALSE;
608 pVideoRenderer->bAggregatable = FALSE;
609 pVideoRenderer->IInner_vtbl = &IInner_VTable;
611 pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl;
612 pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable;
613 pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable;
615 pVideoRenderer->refCount = 1;
616 InitializeCriticalSection(&pVideoRenderer->csFilter);
617 pVideoRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter");
618 pVideoRenderer->state = State_Stopped;
619 pVideoRenderer->pClock = NULL;
620 pVideoRenderer->init = 0;
621 pVideoRenderer->AutoShow = 1;
622 pVideoRenderer->rtLastStop = -1;
623 ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
624 ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT));
625 ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT));
626 ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT));
627 pVideoRenderer->hWndMsgDrain = NULL;
628 pVideoRenderer->WindowStyle = WS_OVERLAPPED;
630 /* construct input pin */
631 piInput.dir = PINDIR_INPUT;
632 piInput.pFilter = (IBaseFilter *)pVideoRenderer;
633 lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
635 hr = InputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, NULL, &pVideoRenderer->csFilter, NULL, (IPin **)&pVideoRenderer->pInputPin);
639 MediaSeekingImpl_Init((IBaseFilter*)pVideoRenderer, VideoRendererImpl_Change, VideoRendererImpl_Change, VideoRendererImpl_Change, &pVideoRenderer->mediaSeeking, &pVideoRenderer->csFilter);
640 pVideoRenderer->mediaSeeking.lpVtbl = &VideoRendererImpl_Seeking_Vtbl;
642 pVideoRenderer->sample_held = NULL;
643 *ppv = pVideoRenderer;
647 pVideoRenderer->csFilter.DebugInfo->Spare[0] = 0;
648 DeleteCriticalSection(&pVideoRenderer->csFilter);
649 CoTaskMemFree(pVideoRenderer);
652 if (!CreateRenderingSubsystem(pVideoRenderer))
655 pVideoRenderer->blocked = CreateEventW(NULL, FALSE, FALSE, NULL);
656 if (!pVideoRenderer->blocked)
658 hr = HRESULT_FROM_WIN32(GetLastError());
659 IUnknown_Release((IUnknown *)pVideoRenderer);
665 HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv)
667 /* TODO: Attempt to use the VMR-7 renderer instead when possible */
668 return VideoRenderer_create(pUnkOuter, ppv);
671 static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
673 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface);
674 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
676 if (This->bAggregatable)
677 This->bUnkOuterValid = TRUE;
681 if (IsEqualIID(riid, &IID_IUnknown))
682 *ppv = &This->IInner_vtbl;
683 else if (IsEqualIID(riid, &IID_IPersist))
685 else if (IsEqualIID(riid, &IID_IMediaFilter))
687 else if (IsEqualIID(riid, &IID_IBaseFilter))
689 else if (IsEqualIID(riid, &IID_IBasicVideo))
690 *ppv = &This->IBasicVideo_vtbl;
691 else if (IsEqualIID(riid, &IID_IVideoWindow))
692 *ppv = &This->IVideoWindow_vtbl;
693 else if (IsEqualIID(riid, &IID_IMediaSeeking))
694 *ppv = &This->mediaSeeking;
698 IUnknown_AddRef((IUnknown *)(*ppv));
702 if (!IsEqualIID(riid, &IID_IPin))
703 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
705 return E_NOINTERFACE;
708 static ULONG WINAPI VideoRendererInner_AddRef(IUnknown * iface)
710 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface);
711 ULONG refCount = InterlockedIncrement(&This->refCount);
713 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
718 static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface)
720 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface);
721 ULONG refCount = InterlockedDecrement(&This->refCount);
723 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
729 DestroyWindow(This->hWnd);
730 PostThreadMessageA(This->ThreadID, WM_QUIT, 0, 0);
731 WaitForSingleObject(This->hThread, INFINITE);
732 CloseHandle(This->hThread);
733 CloseHandle(This->hEvent);
736 IReferenceClock_Release(This->pClock);
738 if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
740 IPin_Disconnect(pConnectedTo);
741 IPin_Release(pConnectedTo);
743 IPin_Disconnect((IPin *)This->pInputPin);
745 IPin_Release((IPin *)This->pInputPin);
749 This->csFilter.DebugInfo->Spare[0] = 0;
750 DeleteCriticalSection(&This->csFilter);
752 TRACE("Destroying Video Renderer\n");
761 static const IUnknownVtbl IInner_VTable =
763 VideoRendererInner_QueryInterface,
764 VideoRendererInner_AddRef,
765 VideoRendererInner_Release
768 static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
770 VideoRendererImpl *This = (VideoRendererImpl *)iface;
772 if (This->bAggregatable)
773 This->bUnkOuterValid = TRUE;
777 if (This->bAggregatable)
778 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
780 if (IsEqualIID(riid, &IID_IUnknown))
784 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
785 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
786 IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
787 This->bAggregatable = TRUE;
792 return E_NOINTERFACE;
795 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
798 static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface)
800 VideoRendererImpl *This = (VideoRendererImpl *)iface;
802 if (This->pUnkOuter && This->bUnkOuterValid)
803 return IUnknown_AddRef(This->pUnkOuter);
804 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
807 static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface)
809 VideoRendererImpl *This = (VideoRendererImpl *)iface;
811 if (This->pUnkOuter && This->bUnkOuterValid)
812 return IUnknown_Release(This->pUnkOuter);
813 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
816 /** IPersist methods **/
818 static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid)
820 VideoRendererImpl *This = (VideoRendererImpl *)iface;
822 TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
824 *pClsid = CLSID_VideoRenderer;
829 /** IMediaFilter methods **/
831 static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
833 VideoRendererImpl *This = (VideoRendererImpl *)iface;
835 TRACE("(%p/%p)->()\n", This, iface);
837 EnterCriticalSection(&This->csFilter);
839 This->state = State_Stopped;
840 SetEvent(This->hEvent);
841 SetEvent(This->blocked);
843 LeaveCriticalSection(&This->csFilter);
848 static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
850 VideoRendererImpl *This = (VideoRendererImpl *)iface;
852 TRACE("(%p/%p)->()\n", This, iface);
854 EnterCriticalSection(&This->csFilter);
855 if (This->state != State_Paused)
857 if (This->state == State_Stopped)
859 This->pInputPin->end_of_stream = 0;
860 ResetEvent(This->hEvent);
863 This->state = State_Paused;
864 ResetEvent(This->blocked);
866 LeaveCriticalSection(&This->csFilter);
871 static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
873 VideoRendererImpl *This = (VideoRendererImpl *)iface;
875 TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
877 EnterCriticalSection(&This->csFilter);
878 if (This->state != State_Running)
880 if (This->state == State_Stopped)
882 This->pInputPin->end_of_stream = 0;
883 ResetEvent(This->hEvent);
885 SetEvent(This->blocked);
887 This->rtStreamStart = tStart;
888 This->state = State_Running;
890 LeaveCriticalSection(&This->csFilter);
895 static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
897 VideoRendererImpl *This = (VideoRendererImpl *)iface;
900 TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState);
902 if (WaitForSingleObject(This->hEvent, dwMilliSecsTimeout) == WAIT_TIMEOUT)
903 hr = VFW_S_STATE_INTERMEDIATE;
907 EnterCriticalSection(&This->csFilter);
909 *pState = This->state;
911 LeaveCriticalSection(&This->csFilter);
916 static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
918 VideoRendererImpl *This = (VideoRendererImpl *)iface;
920 TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
922 EnterCriticalSection(&This->csFilter);
925 IReferenceClock_Release(This->pClock);
926 This->pClock = pClock;
928 IReferenceClock_AddRef(This->pClock);
930 LeaveCriticalSection(&This->csFilter);
935 static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
937 VideoRendererImpl *This = (VideoRendererImpl *)iface;
939 TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
941 EnterCriticalSection(&This->csFilter);
943 *ppClock = This->pClock;
945 IReferenceClock_AddRef(This->pClock);
947 LeaveCriticalSection(&This->csFilter);
952 /** IBaseFilter implementation **/
954 static HRESULT VideoRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
956 VideoRendererImpl *This = (VideoRendererImpl *)iface;
958 /* Our pins are static, not changing so setting static tick count is ok */
964 *pin = (IPin *)This->pInputPin;
969 static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
971 VideoRendererImpl *This = (VideoRendererImpl *)iface;
973 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
975 return IEnumPinsImpl_Construct(ppEnum, VideoRenderer_GetPin, iface);
978 static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
980 VideoRendererImpl *This = (VideoRendererImpl *)iface;
982 FIXME("(%p/%p)->(%p,%p): stub !!!\n", This, iface, debugstr_w(Id), ppPin);
984 /* FIXME: critical section */
989 static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
991 VideoRendererImpl *This = (VideoRendererImpl *)iface;
993 TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
995 strcpyW(pInfo->achName, This->filterInfo.achName);
996 pInfo->pGraph = This->filterInfo.pGraph;
999 IFilterGraph_AddRef(pInfo->pGraph);
1004 static HRESULT WINAPI VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
1006 VideoRendererImpl *This = (VideoRendererImpl *)iface;
1008 TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
1010 EnterCriticalSection(&This->csFilter);
1013 strcpyW(This->filterInfo.achName, pName);
1015 *This->filterInfo.achName = '\0';
1016 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
1018 LeaveCriticalSection(&This->csFilter);
1023 static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
1025 VideoRendererImpl *This = (VideoRendererImpl *)iface;
1026 TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
1030 static const IBaseFilterVtbl VideoRenderer_Vtbl =
1032 VideoRenderer_QueryInterface,
1033 VideoRenderer_AddRef,
1034 VideoRenderer_Release,
1035 VideoRenderer_GetClassID,
1037 VideoRenderer_Pause,
1039 VideoRenderer_GetState,
1040 VideoRenderer_SetSyncSource,
1041 VideoRenderer_GetSyncSource,
1042 VideoRenderer_EnumPins,
1043 VideoRenderer_FindPin,
1044 VideoRenderer_QueryFilterInfo,
1045 VideoRenderer_JoinFilterGraph,
1046 VideoRenderer_QueryVendorInfo
1049 static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
1051 InputPin* This = (InputPin*)iface;
1052 IMediaEventSink* pEventSink;
1055 TRACE("(%p/%p)->()\n", This, iface);
1057 hr = IFilterGraph_QueryInterface(((VideoRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
1060 hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0);
1061 IMediaEventSink_Release(pEventSink);
1067 static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface)
1069 InputPin* This = (InputPin*)iface;
1070 VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter;
1073 TRACE("(%p/%p)->()\n", This, iface);
1075 EnterCriticalSection(This->pin.pCritSec);
1076 if (pVideoRenderer->state == State_Paused)
1077 SetEvent(pVideoRenderer->blocked);
1079 hr = InputPin_BeginFlush(iface);
1080 LeaveCriticalSection(This->pin.pCritSec);
1085 static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
1087 InputPin* This = (InputPin*)iface;
1088 VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter;
1091 TRACE("(%p/%p)->()\n", This, iface);
1093 EnterCriticalSection(This->pin.pCritSec);
1094 if (pVideoRenderer->state == State_Paused)
1095 ResetEvent(pVideoRenderer->blocked);
1097 hr = InputPin_EndFlush(iface);
1098 LeaveCriticalSection(This->pin.pCritSec);
1103 static const IPinVtbl VideoRenderer_InputPin_Vtbl =
1105 InputPin_QueryInterface,
1109 InputPin_ReceiveConnection,
1110 IPinImpl_Disconnect,
1111 IPinImpl_ConnectedTo,
1112 IPinImpl_ConnectionMediaType,
1113 IPinImpl_QueryPinInfo,
1114 IPinImpl_QueryDirection,
1116 IPinImpl_QueryAccept,
1117 IPinImpl_EnumMediaTypes,
1118 IPinImpl_QueryInternalConnections,
1119 VideoRenderer_InputPin_EndOfStream,
1120 VideoRenderer_InputPin_BeginFlush,
1121 VideoRenderer_InputPin_EndFlush,
1125 /*** IUnknown methods ***/
1126 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface,
1129 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1131 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1133 return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
1136 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) {
1137 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1139 TRACE("(%p/%p)->()\n", This, iface);
1141 return VideoRenderer_AddRef((IBaseFilter*)This);
1144 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) {
1145 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1147 TRACE("(%p/%p)->()\n", This, iface);
1149 return VideoRenderer_Release((IBaseFilter*)This);
1152 /*** IDispatch methods ***/
1153 static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface,
1155 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1157 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1162 static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface,
1165 ITypeInfo**ppTInfo) {
1166 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1168 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1173 static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface,
1179 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1181 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1186 static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface,
1187 DISPID dispIdMember,
1191 DISPPARAMS*pDispParams,
1193 EXCEPINFO*pExepInfo,
1195 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1197 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);
1202 /*** IBasicVideo methods ***/
1203 static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface,
1204 REFTIME *pAvgTimePerFrame) {
1206 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1208 if (!This->pInputPin->pin.pConnectedTo)
1209 return VFW_E_NOT_CONNECTED;
1211 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
1213 pmt = &This->pInputPin->pin.mtCurrent;
1214 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
1215 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat;
1216 *pAvgTimePerFrame = vih->AvgTimePerFrame;
1217 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
1218 VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat;
1219 *pAvgTimePerFrame = vih->AvgTimePerFrame;
1221 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
1222 *pAvgTimePerFrame = 0;
1227 static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface,
1229 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1231 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate);
1236 static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface,
1237 LONG *pBitErrorRate) {
1238 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1240 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate);
1245 static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface,
1246 LONG *pVideoWidth) {
1247 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1249 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
1251 *pVideoWidth = This->VideoWidth;
1256 static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface,
1257 LONG *pVideoHeight) {
1258 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1260 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
1262 *pVideoHeight = This->VideoHeight;
1267 static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface,
1269 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1271 TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft);
1273 This->SourceRect.left = SourceLeft;
1278 static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface,
1279 LONG *pSourceLeft) {
1280 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1282 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
1284 *pSourceLeft = This->SourceRect.left;
1289 static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface,
1291 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1293 TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth);
1295 This->SourceRect.right = This->SourceRect.left + SourceWidth;
1300 static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface,
1301 LONG *pSourceWidth) {
1302 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1304 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
1306 *pSourceWidth = This->SourceRect.right - This->SourceRect.left;
1311 static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface,
1313 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1315 TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop);
1317 This->SourceRect.top = SourceTop;
1322 static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface,
1324 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1326 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
1328 *pSourceTop = This->SourceRect.top;
1333 static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface,
1334 LONG SourceHeight) {
1335 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1337 TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight);
1339 This->SourceRect.bottom = This->SourceRect.top + SourceHeight;
1344 static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface,
1345 LONG *pSourceHeight) {
1346 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1348 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
1350 *pSourceHeight = This->SourceRect.bottom - This->SourceRect.top;
1355 static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface,
1356 LONG DestinationLeft) {
1357 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1359 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft);
1361 This->DestRect.left = DestinationLeft;
1366 static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface,
1367 LONG *pDestinationLeft) {
1368 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1370 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
1372 *pDestinationLeft = This->DestRect.left;
1377 static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface,
1378 LONG DestinationWidth) {
1379 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1381 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth);
1383 This->DestRect.right = This->DestRect.left + DestinationWidth;
1388 static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface,
1389 LONG *pDestinationWidth) {
1390 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1392 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
1394 *pDestinationWidth = This->DestRect.right - This->DestRect.left;
1399 static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface,
1400 LONG DestinationTop) {
1401 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1403 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop);
1405 This->DestRect.top = DestinationTop;
1410 static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface,
1411 LONG *pDestinationTop) {
1412 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1414 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
1416 *pDestinationTop = This->DestRect.top;
1421 static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface,
1422 LONG DestinationHeight) {
1423 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1425 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight);
1427 This->DestRect.right = This->DestRect.left + DestinationHeight;
1432 static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface,
1433 LONG *pDestinationHeight) {
1434 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1436 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
1438 *pDestinationHeight = This->DestRect.right - This->DestRect.left;
1443 static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface,
1448 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1450 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
1452 This->SourceRect.left = Left;
1453 This->SourceRect.top = Top;
1454 This->SourceRect.right = Left + Width;
1455 This->SourceRect.bottom = Top + Height;
1460 static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface,
1465 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1467 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
1469 *pLeft = This->SourceRect.left;
1470 *pTop = This->SourceRect.top;
1471 *pWidth = This->SourceRect.right - This->SourceRect.left;
1472 *pHeight = This->SourceRect.bottom - This->SourceRect.top;
1477 static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) {
1478 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1480 TRACE("(%p/%p)->()\n", This, iface);
1482 This->SourceRect.left = 0;
1483 This->SourceRect.top = 0;
1484 This->SourceRect.right = This->VideoWidth;
1485 This->SourceRect.bottom = This->VideoHeight;
1490 static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface,
1495 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1497 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
1499 This->DestRect.left = Left;
1500 This->DestRect.top = Top;
1501 This->DestRect.right = Left + Width;
1502 This->DestRect.bottom = Top + Height;
1507 static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface,
1512 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1514 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
1516 *pLeft = This->DestRect.left;
1517 *pTop = This->DestRect.top;
1518 *pWidth = This->DestRect.right - This->DestRect.left;
1519 *pHeight = This->DestRect.bottom - This->DestRect.top;
1524 static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
1525 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1528 TRACE("(%p/%p)->()\n", This, iface);
1530 if (!GetClientRect(This->hWnd, &rect))
1533 This->SourceRect.left = 0;
1534 This->SourceRect.top = 0;
1535 This->SourceRect.right = rect.right;
1536 This->SourceRect.bottom = rect.bottom;
1541 static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface,
1544 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1546 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
1548 *pWidth = This->VideoWidth;
1549 *pHeight = This->VideoHeight;
1554 static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface,
1559 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1561 FIXME("(%p/%p)->(%d, %d, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
1566 static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
1569 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1570 BITMAPINFOHEADER *bmiHeader;
1572 AM_MEDIA_TYPE *amt = &This->pInputPin->pin.mtCurrent;
1575 FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage);
1577 EnterCriticalSection(&This->csFilter);
1579 if (!This->sample_held)
1581 LeaveCriticalSection(&This->csFilter);
1582 return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
1585 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
1587 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
1589 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
1591 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
1595 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
1596 LeaveCriticalSection(&This->csFilter);
1597 return VFW_E_RUNTIME_ERROR;
1600 needed_size = bmiHeader->biSize;
1601 needed_size += IMediaSample_GetActualDataLength(This->sample_held);
1605 *pBufferSize = needed_size;
1606 LeaveCriticalSection(&This->csFilter);
1610 if (needed_size < *pBufferSize)
1612 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
1613 LeaveCriticalSection(&This->csFilter);
1616 *pBufferSize = needed_size;
1618 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
1619 IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr);
1620 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held));
1622 LeaveCriticalSection(&This->csFilter);
1627 static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) {
1628 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1630 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
1635 static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) {
1636 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1638 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
1644 static const IBasicVideoVtbl IBasicVideo_VTable =
1646 Basicvideo_QueryInterface,
1649 Basicvideo_GetTypeInfoCount,
1650 Basicvideo_GetTypeInfo,
1651 Basicvideo_GetIDsOfNames,
1653 Basicvideo_get_AvgTimePerFrame,
1654 Basicvideo_get_BitRate,
1655 Basicvideo_get_BitErrorRate,
1656 Basicvideo_get_VideoWidth,
1657 Basicvideo_get_VideoHeight,
1658 Basicvideo_put_SourceLeft,
1659 Basicvideo_get_SourceLeft,
1660 Basicvideo_put_SourceWidth,
1661 Basicvideo_get_SourceWidth,
1662 Basicvideo_put_SourceTop,
1663 Basicvideo_get_SourceTop,
1664 Basicvideo_put_SourceHeight,
1665 Basicvideo_get_SourceHeight,
1666 Basicvideo_put_DestinationLeft,
1667 Basicvideo_get_DestinationLeft,
1668 Basicvideo_put_DestinationWidth,
1669 Basicvideo_get_DestinationWidth,
1670 Basicvideo_put_DestinationTop,
1671 Basicvideo_get_DestinationTop,
1672 Basicvideo_put_DestinationHeight,
1673 Basicvideo_get_DestinationHeight,
1674 Basicvideo_SetSourcePosition,
1675 Basicvideo_GetSourcePosition,
1676 Basicvideo_SetDefaultSourcePosition,
1677 Basicvideo_SetDestinationPosition,
1678 Basicvideo_GetDestinationPosition,
1679 Basicvideo_SetDefaultDestinationPosition,
1680 Basicvideo_GetVideoSize,
1681 Basicvideo_GetVideoPaletteEntries,
1682 Basicvideo_GetCurrentImage,
1683 Basicvideo_IsUsingDefaultSource,
1684 Basicvideo_IsUsingDefaultDestination
1688 /*** IUnknown methods ***/
1689 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface,
1692 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1694 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1696 return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
1699 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) {
1700 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1702 TRACE("(%p/%p)->()\n", This, iface);
1704 return VideoRenderer_AddRef((IBaseFilter*)This);
1707 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) {
1708 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1710 TRACE("(%p/%p)->()\n", This, iface);
1712 return VideoRenderer_Release((IBaseFilter*)This);
1715 /*** IDispatch methods ***/
1716 static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface,
1718 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1720 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1725 static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface,
1728 ITypeInfo**ppTInfo) {
1729 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1731 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1736 static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface,
1742 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1744 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1749 static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface,
1750 DISPID dispIdMember,
1754 DISPPARAMS*pDispParams,
1756 EXCEPINFO*pExepInfo,
1758 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1760 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);
1765 /*** IVideoWindow methods ***/
1766 static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface,
1768 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1770 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
1772 if (!SetWindowTextW(This->hWnd, strCaption))
1778 static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface,
1780 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1782 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
1784 GetWindowTextW(This->hWnd, (LPWSTR)strCaption, 100);
1789 static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface,
1791 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1794 old = GetWindowLongA(This->hWnd, GWL_STYLE);
1796 TRACE("(%p/%p)->(%x -> %x)\n", This, iface, old, WindowStyle);
1798 if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL))
1799 return E_INVALIDARG;
1801 SetWindowLongA(This->hWnd, GWL_STYLE, WindowStyle);
1802 SetWindowPos(This->hWnd,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOZORDER);
1803 This->WindowStyle = WindowStyle;
1808 static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface,
1809 LONG *WindowStyle) {
1810 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1812 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
1814 *WindowStyle = This->WindowStyle;
1819 static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface,
1820 LONG WindowStyleEx) {
1821 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1823 TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx);
1825 if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx))
1831 static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface,
1832 LONG *WindowStyleEx) {
1833 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1835 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
1837 *WindowStyleEx = GetWindowLongA(This->hWnd, GWL_EXSTYLE);
1842 static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface,
1844 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1846 TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow);
1848 This->AutoShow = AutoShow;
1853 static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface,
1855 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1857 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
1859 *AutoShow = This->AutoShow;
1864 static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface,
1866 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1868 TRACE("(%p/%p)->(%d)\n", This, iface, WindowState);
1869 ShowWindow(This->hWnd, WindowState);
1873 static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface,
1874 LONG *WindowState) {
1875 WINDOWPLACEMENT place;
1876 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1878 place.length = sizeof(place);
1879 GetWindowPlacement(This->hWnd, &place);
1880 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
1881 *WindowState = place.showCmd;
1886 static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface,
1887 LONG BackgroundPalette) {
1888 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1890 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, BackgroundPalette);
1895 static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface,
1896 LONG *pBackgroundPalette) {
1897 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1899 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette);
1904 static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface,
1906 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1908 TRACE("(%p/%p)->(%d)\n", This, iface, Visible);
1910 ShowWindow(This->hWnd, Visible ? SW_SHOW : SW_HIDE);
1915 static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface,
1917 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1919 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
1921 *pVisible = IsWindowVisible(This->hWnd);
1926 static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface,
1928 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1930 TRACE("(%p/%p)->(%d)\n", This, iface, Left);
1932 if (!SetWindowPos(This->hWnd, NULL, Left, This->WindowPos.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE))
1935 This->WindowPos.left = Left;
1940 static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface,
1942 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1944 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
1946 *pLeft = This->WindowPos.left;
1951 static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface,
1953 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1955 TRACE("(%p/%p)->(%d)\n", This, iface, Width);
1957 if (!SetWindowPos(This->hWnd, NULL, 0, 0, Width, This->WindowPos.bottom-This->WindowPos.top, SWP_NOZORDER|SWP_NOMOVE))
1960 This->WindowPos.right = This->WindowPos.left + Width;
1965 static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface,
1967 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1969 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
1971 *pWidth = This->WindowPos.right - This->WindowPos.left;
1976 static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface,
1978 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1980 TRACE("(%p/%p)->(%d)\n", This, iface, Top);
1982 if (!SetWindowPos(This->hWnd, NULL, This->WindowPos.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE))
1985 This->WindowPos.top = Top;
1990 static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface,
1992 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1994 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
1996 *pTop = This->WindowPos.top;
2001 static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface,
2003 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2005 TRACE("(%p/%p)->(%d)\n", This, iface, Height);
2007 if (!SetWindowPos(This->hWnd, NULL, 0, 0, This->WindowPos.right-This->WindowPos.left, Height, SWP_NOZORDER|SWP_NOMOVE))
2010 This->WindowPos.bottom = This->WindowPos.top + Height;
2015 static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface,
2017 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2019 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
2021 *pHeight = This->WindowPos.bottom - This->WindowPos.top;
2026 static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface,
2028 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2030 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
2032 SetParent(This->hWnd, (HWND)Owner);
2033 if (This->WindowStyle & WS_CHILD)
2035 LONG old = GetWindowLongA(This->hWnd, GWL_STYLE);
2036 if (old != This->WindowStyle)
2038 SetWindowLongA(This->hWnd, GWL_STYLE, This->WindowStyle);
2039 SetWindowPos(This->hWnd,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOZORDER);
2046 static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface,
2048 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2050 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
2052 *(HWND*)Owner = GetParent(This->hWnd);
2057 static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface,
2059 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2061 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
2063 This->hWndMsgDrain = (HWND)Drain;
2068 static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface,
2070 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2072 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
2074 *Drain = (OAHWND)This->hWndMsgDrain;
2079 static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface,
2081 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2083 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color);
2088 static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface,
2090 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2092 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, Color);
2097 static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface,
2098 LONG *FullScreenMode) {
2099 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2101 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode);
2106 static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface,
2107 LONG FullScreenMode) {
2108 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2110 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, FullScreenMode);
2115 static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface,
2117 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2122 TRACE("(%p/%p)->(%d)\n", This, iface, Focus);
2124 if ((Focus != FALSE) && (Focus != TRUE))
2125 return E_INVALIDARG;
2127 hr = IPin_ConnectedTo((IPin *)This->pInputPin, &pPin);
2128 if ((hr != S_OK) || !pPin)
2129 return VFW_E_NOT_CONNECTED;
2132 ret = SetForegroundWindow(This->hWnd);
2134 ret = SetWindowPos(This->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2142 static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface,
2147 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2149 TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam);
2151 if (!PostMessageA(This->hWnd, uMsg, wParam, lParam))
2157 static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface,
2162 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2164 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
2166 if (!SetWindowPos(This->hWnd, NULL, Left, Top, Width, Height, SWP_NOZORDER))
2169 This->WindowPos.left = Left;
2170 This->WindowPos.top = Top;
2171 This->WindowPos.right = Left + Width;
2172 This->WindowPos.bottom = Top + Height;
2177 static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface,
2182 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2184 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
2186 *pLeft = This->WindowPos.left;
2187 *pTop = This->WindowPos.top;
2188 *pWidth = This->WindowPos.right - This->WindowPos.left;
2189 *pHeight = This->WindowPos.bottom - This->WindowPos.top;
2194 static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface,
2197 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2199 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight);
2201 *pWidth = This->VideoWidth;
2202 *pHeight = This->VideoHeight;
2207 static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface,
2210 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2212 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight);
2214 *pWidth = This->VideoWidth;
2215 *pHeight = This->VideoHeight;
2220 static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface,
2225 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2227 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
2232 static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface,
2234 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2236 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, HideCursor);
2241 static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface,
2242 LONG *CursorHidden) {
2243 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
2245 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden);
2250 static const IVideoWindowVtbl IVideoWindow_VTable =
2252 Videowindow_QueryInterface,
2254 Videowindow_Release,
2255 Videowindow_GetTypeInfoCount,
2256 Videowindow_GetTypeInfo,
2257 Videowindow_GetIDsOfNames,
2259 Videowindow_put_Caption,
2260 Videowindow_get_Caption,
2261 Videowindow_put_WindowStyle,
2262 Videowindow_get_WindowStyle,
2263 Videowindow_put_WindowStyleEx,
2264 Videowindow_get_WindowStyleEx,
2265 Videowindow_put_AutoShow,
2266 Videowindow_get_AutoShow,
2267 Videowindow_put_WindowState,
2268 Videowindow_get_WindowState,
2269 Videowindow_put_BackgroundPalette,
2270 Videowindow_get_BackgroundPalette,
2271 Videowindow_put_Visible,
2272 Videowindow_get_Visible,
2273 Videowindow_put_Left,
2274 Videowindow_get_Left,
2275 Videowindow_put_Width,
2276 Videowindow_get_Width,
2277 Videowindow_put_Top,
2278 Videowindow_get_Top,
2279 Videowindow_put_Height,
2280 Videowindow_get_Height,
2281 Videowindow_put_Owner,
2282 Videowindow_get_Owner,
2283 Videowindow_put_MessageDrain,
2284 Videowindow_get_MessageDrain,
2285 Videowindow_get_BorderColor,
2286 Videowindow_put_BorderColor,
2287 Videowindow_get_FullScreenMode,
2288 Videowindow_put_FullScreenMode,
2289 Videowindow_SetWindowForeground,
2290 Videowindow_NotifyOwnerMessage,
2291 Videowindow_SetWindowPosition,
2292 Videowindow_GetWindowPosition,
2293 Videowindow_GetMinIdealImageSize,
2294 Videowindow_GetMaxIdealImageSize,
2295 Videowindow_GetRestorePosition,
2296 Videowindow_HideCursor,
2297 Videowindow_IsCursorHidden