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
21 #include "quartz_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
39 typedef struct VideoRendererImpl
41 BaseRenderer renderer
;
42 BaseControlWindow baseControlWindow
;
43 BaseControlVideo baseControlVideo
;
45 IOverlay IOverlay_iface
;
60 static inline VideoRendererImpl
*impl_from_BaseWindow(BaseWindow
*iface
)
62 return CONTAINING_RECORD(iface
, VideoRendererImpl
, baseControlWindow
.baseWindow
);
65 static inline VideoRendererImpl
*impl_from_BaseRenderer(BaseRenderer
*iface
)
67 return CONTAINING_RECORD(iface
, VideoRendererImpl
, renderer
);
70 static inline VideoRendererImpl
*impl_from_IBaseFilter(IBaseFilter
*iface
)
72 return CONTAINING_RECORD(iface
, VideoRendererImpl
, renderer
.filter
.IBaseFilter_iface
);
75 static inline VideoRendererImpl
*impl_from_IVideoWindow(IVideoWindow
*iface
)
77 return CONTAINING_RECORD(iface
, VideoRendererImpl
, baseControlWindow
.IVideoWindow_iface
);
80 static inline VideoRendererImpl
*impl_from_BaseControlVideo(BaseControlVideo
*iface
)
82 return CONTAINING_RECORD(iface
, VideoRendererImpl
, baseControlVideo
);
85 static void VideoRenderer_AutoShowWindow(VideoRendererImpl
*This
)
87 if (!This
->init
&& (!This
->WindowPos
.right
|| !This
->WindowPos
.top
))
89 DWORD style
= GetWindowLongW(This
->baseControlWindow
.baseWindow
.hWnd
, GWL_STYLE
);
90 DWORD style_ex
= GetWindowLongW(This
->baseControlWindow
.baseWindow
.hWnd
, GWL_EXSTYLE
);
92 if (!This
->WindowPos
.right
)
94 if (This
->DestRect
.right
)
96 This
->WindowPos
.left
= This
->DestRect
.left
;
97 This
->WindowPos
.right
= This
->DestRect
.right
;
101 This
->WindowPos
.left
= This
->SourceRect
.left
;
102 This
->WindowPos
.right
= This
->SourceRect
.right
;
105 if (!This
->WindowPos
.bottom
)
107 if (This
->DestRect
.bottom
)
109 This
->WindowPos
.top
= This
->DestRect
.top
;
110 This
->WindowPos
.bottom
= This
->DestRect
.bottom
;
114 This
->WindowPos
.top
= This
->SourceRect
.top
;
115 This
->WindowPos
.bottom
= This
->SourceRect
.bottom
;
119 AdjustWindowRectEx(&This
->WindowPos
, style
, FALSE
, style_ex
);
121 TRACE("WindowPos: %s\n", wine_dbgstr_rect(&This
->WindowPos
));
122 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
,
123 This
->WindowPos
.left
,
125 This
->WindowPos
.right
- This
->WindowPos
.left
,
126 This
->WindowPos
.bottom
- This
->WindowPos
.top
,
127 SWP_NOZORDER
|SWP_NOMOVE
|SWP_DEFERERASE
);
129 GetClientRect(This
->baseControlWindow
.baseWindow
.hWnd
, &This
->DestRect
);
131 else if (!This
->init
)
132 This
->DestRect
= This
->WindowPos
;
134 if (This
->baseControlWindow
.AutoShow
)
135 ShowWindow(This
->baseControlWindow
.baseWindow
.hWnd
, SW_SHOW
);
138 static DWORD
VideoRenderer_SendSampleData(VideoRendererImpl
* This
, LPBYTE data
, DWORD size
)
142 BITMAPINFOHEADER
*bmiHeader
;
145 TRACE("(%p)->(%p, %d)\n", This
, data
, size
);
147 hr
= IPin_ConnectionMediaType(&This
->renderer
.sink
.pin
.IPin_iface
, &amt
);
149 ERR("Unable to retrieve media type\n");
153 if (IsEqualIID(&amt
.formattype
, &FORMAT_VideoInfo
))
155 bmiHeader
= &((VIDEOINFOHEADER
*)amt
.pbFormat
)->bmiHeader
;
157 else if (IsEqualIID(&amt
.formattype
, &FORMAT_VideoInfo2
))
159 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
.pbFormat
)->bmiHeader
;
163 FIXME("Unknown type %s\n", debugstr_guid(&amt
.subtype
));
164 return VFW_E_RUNTIME_ERROR
;
167 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This
->SourceRect
));
168 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This
->DestRect
));
170 dc
= GetDC(This
->baseControlWindow
.baseWindow
.hWnd
);
171 StretchDIBits(dc
, This
->DestRect
.left
, This
->DestRect
.top
, This
->DestRect
.right
-This
->DestRect
.left
,
172 This
->DestRect
.bottom
- This
->DestRect
.top
, This
->SourceRect
.left
, This
->SourceRect
.top
,
173 This
->SourceRect
.right
- This
->SourceRect
.left
, This
->SourceRect
.bottom
- This
->SourceRect
.top
,
174 data
, (BITMAPINFO
*)bmiHeader
, DIB_RGB_COLORS
, SRCCOPY
);
175 ReleaseDC(This
->baseControlWindow
.baseWindow
.hWnd
, dc
);
180 static HRESULT WINAPI
VideoRenderer_ShouldDrawSampleNow(BaseRenderer
*This
, IMediaSample
*pSample
, REFERENCE_TIME
*pStartTime
, REFERENCE_TIME
*pEndTime
)
182 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
183 if (IMediaSample_IsPreroll(pSample
) == S_OK
)
188 static HRESULT WINAPI
VideoRenderer_DoRenderSample(BaseRenderer
* iface
, IMediaSample
* pSample
)
190 VideoRendererImpl
*This
= impl_from_BaseRenderer(iface
);
191 LPBYTE pbSrcStream
= NULL
;
192 LONG cbSrcStream
= 0;
195 TRACE("(%p)->(%p)\n", This
, pSample
);
197 hr
= IMediaSample_GetPointer(pSample
, &pbSrcStream
);
200 ERR("Cannot get pointer to sample data (%x)\n", hr
);
204 cbSrcStream
= IMediaSample_GetActualDataLength(pSample
);
206 TRACE("val %p %d\n", pbSrcStream
, cbSrcStream
);
208 #if 0 /* For debugging purpose */
211 for(i
= 0; i
< cbSrcStream
; i
++)
213 if ((i
!=0) && !(i
%16))
215 TRACE("%02x ", pbSrcStream
[i
]);
221 SetEvent(This
->hEvent
);
222 if (This
->renderer
.filter
.state
== State_Paused
)
224 VideoRenderer_SendSampleData(This
, pbSrcStream
, cbSrcStream
);
225 SetEvent(This
->hEvent
);
226 if (This
->renderer
.filter
.state
== State_Paused
)
231 if (This
->renderer
.filter
.state
== State_Stopped
)
233 return VFW_E_WRONG_STATE
;
236 VideoRenderer_SendSampleData(This
, pbSrcStream
, cbSrcStream
);
241 static HRESULT WINAPI
VideoRenderer_CheckMediaType(BaseRenderer
*iface
, const AM_MEDIA_TYPE
* pmt
)
243 VideoRendererImpl
*This
= impl_from_BaseRenderer(iface
);
245 if (!IsEqualIID(&pmt
->majortype
, &MEDIATYPE_Video
))
248 if (IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB32
) ||
249 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB24
) ||
250 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB565
) ||
251 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB8
))
255 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
))
257 VIDEOINFOHEADER
*format
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
258 This
->SourceRect
.left
= 0;
259 This
->SourceRect
.top
= 0;
260 This
->SourceRect
.right
= This
->VideoWidth
= format
->bmiHeader
.biWidth
;
261 height
= format
->bmiHeader
.biHeight
;
263 This
->SourceRect
.bottom
= This
->VideoHeight
= -height
;
265 This
->SourceRect
.bottom
= This
->VideoHeight
= height
;
267 else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
))
269 VIDEOINFOHEADER2
*format2
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
271 This
->SourceRect
.left
= 0;
272 This
->SourceRect
.top
= 0;
273 This
->SourceRect
.right
= This
->VideoWidth
= format2
->bmiHeader
.biWidth
;
274 height
= format2
->bmiHeader
.biHeight
;
276 This
->SourceRect
.bottom
= This
->VideoHeight
= -height
;
278 This
->SourceRect
.bottom
= This
->VideoHeight
= height
;
282 WARN("Format type %s not supported\n", debugstr_guid(&pmt
->formattype
));
290 static HRESULT WINAPI
VideoRenderer_EndFlush(BaseRenderer
* iface
)
292 VideoRendererImpl
*This
= impl_from_BaseRenderer(iface
);
294 TRACE("(%p)->()\n", iface
);
296 if (This
->renderer
.pMediaSample
) {
297 ResetEvent(This
->hEvent
);
298 LeaveCriticalSection(&iface
->filter
.csFilter
);
299 LeaveCriticalSection(&iface
->csRenderLock
);
300 WaitForSingleObject(This
->hEvent
, INFINITE
);
301 EnterCriticalSection(&iface
->csRenderLock
);
302 EnterCriticalSection(&iface
->filter
.csFilter
);
304 if (This
->renderer
.filter
.state
== State_Paused
) {
305 ResetEvent(This
->hEvent
);
308 return BaseRendererImpl_EndFlush(iface
);
311 static void video_renderer_destroy(BaseRenderer
*iface
)
313 VideoRendererImpl
*filter
= impl_from_BaseRenderer(iface
);
315 BaseControlWindow_Destroy(&filter
->baseControlWindow
);
316 BaseControlVideo_Destroy(&filter
->baseControlVideo
);
317 CloseHandle(filter
->hEvent
);
319 strmbase_renderer_cleanup(&filter
->renderer
);
320 CoTaskMemFree(filter
);
323 static HRESULT
video_renderer_query_interface(BaseRenderer
*iface
, REFIID iid
, void **out
)
325 VideoRendererImpl
*filter
= impl_from_BaseRenderer(iface
);
327 if (IsEqualGUID(iid
, &IID_IBasicVideo
))
328 *out
= &filter
->baseControlVideo
.IBasicVideo_iface
;
329 else if (IsEqualGUID(iid
, &IID_IVideoWindow
))
330 *out
= &filter
->baseControlWindow
.IVideoWindow_iface
;
332 return E_NOINTERFACE
;
334 IUnknown_AddRef((IUnknown
*)*out
);
338 static HRESULT
video_renderer_pin_query_interface(BaseRenderer
*iface
, REFIID iid
, void **out
)
340 VideoRendererImpl
*filter
= impl_from_BaseRenderer(iface
);
342 if (IsEqualGUID(iid
, &IID_IOverlay
))
343 *out
= &filter
->IOverlay_iface
;
345 return E_NOINTERFACE
;
347 IUnknown_AddRef((IUnknown
*)*out
);
351 static void video_renderer_stop_stream(BaseRenderer
*iface
)
353 VideoRendererImpl
*This
= impl_from_BaseRenderer(iface
);
355 TRACE("(%p)->()\n", This
);
357 SetEvent(This
->hEvent
);
358 if (This
->baseControlWindow
.AutoShow
)
360 RedrawWindow(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
, NULL
, RDW_INVALIDATE
|RDW_ERASE
);
363 static void video_renderer_start_stream(BaseRenderer
*iface
)
365 VideoRendererImpl
*This
= impl_from_BaseRenderer(iface
);
367 TRACE("(%p)\n", This
);
369 if (This
->renderer
.sink
.pin
.peer
370 && (This
->renderer
.filter
.state
== State_Stopped
|| !This
->renderer
.sink
.end_of_stream
))
372 if (This
->renderer
.filter
.state
== State_Stopped
)
374 ResetEvent(This
->hEvent
);
375 VideoRenderer_AutoShowWindow(This
);
380 static RECT WINAPI
VideoRenderer_GetDefaultRect(BaseWindow
*iface
)
382 VideoRendererImpl
*This
= impl_from_BaseWindow(iface
);
385 SetRect(&defRect
, 0, 0, This
->VideoWidth
, This
->VideoHeight
);
390 static BOOL WINAPI
VideoRenderer_OnSize(BaseWindow
*iface
, LONG Width
, LONG Height
)
392 VideoRendererImpl
*This
= impl_from_BaseWindow(iface
);
394 TRACE("WM_SIZE %d %d\n", Width
, Height
);
395 GetClientRect(iface
->hWnd
, &This
->DestRect
);
396 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
399 This
->DestRect
.right
- This
->DestRect
.left
,
400 This
->DestRect
.bottom
- This
->DestRect
.top
);
405 static const BaseRendererFuncTable BaseFuncTable
=
407 .pfnCheckMediaType
= VideoRenderer_CheckMediaType
,
408 .pfnDoRenderSample
= VideoRenderer_DoRenderSample
,
409 .renderer_start_stream
= video_renderer_start_stream
,
410 .renderer_stop_stream
= video_renderer_stop_stream
,
411 .pfnShouldDrawSampleNow
= VideoRenderer_ShouldDrawSampleNow
,
412 .pfnEndFlush
= VideoRenderer_EndFlush
,
413 .renderer_destroy
= video_renderer_destroy
,
414 .renderer_query_interface
= video_renderer_query_interface
,
415 .renderer_pin_query_interface
= video_renderer_pin_query_interface
,
418 static const BaseWindowFuncTable renderer_BaseWindowFuncTable
= {
419 VideoRenderer_GetDefaultRect
,
423 static HRESULT WINAPI
VideoRenderer_GetSourceRect(BaseControlVideo
* iface
, RECT
*pSourceRect
)
425 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
426 CopyRect(pSourceRect
,&This
->SourceRect
);
430 static HRESULT WINAPI
VideoRenderer_GetStaticImage(BaseControlVideo
* iface
, LONG
*pBufferSize
, LONG
*pDIBImage
)
432 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
433 AM_MEDIA_TYPE
*amt
= &This
->renderer
.sink
.pin
.mtCurrent
;
434 BITMAPINFOHEADER
*bmiHeader
;
438 FIXME("(%p/%p)->(%p, %p): partial stub\n", This
, iface
, pBufferSize
, pDIBImage
);
440 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
442 if (!This
->renderer
.pMediaSample
)
444 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
445 return (This
->renderer
.filter
.state
== State_Paused
? E_UNEXPECTED
: VFW_E_NOT_PAUSED
);
448 if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo
))
450 bmiHeader
= &((VIDEOINFOHEADER
*)amt
->pbFormat
)->bmiHeader
;
452 else if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo2
))
454 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
->pbFormat
)->bmiHeader
;
458 FIXME("Unknown type %s\n", debugstr_guid(&amt
->subtype
));
459 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
460 return VFW_E_RUNTIME_ERROR
;
463 needed_size
= bmiHeader
->biSize
;
464 needed_size
+= IMediaSample_GetActualDataLength(This
->renderer
.pMediaSample
);
468 *pBufferSize
= needed_size
;
469 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
473 if (needed_size
< *pBufferSize
)
475 ERR("Buffer too small %u/%u\n", needed_size
, *pBufferSize
);
476 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
479 *pBufferSize
= needed_size
;
481 memcpy(pDIBImage
, bmiHeader
, bmiHeader
->biSize
);
482 IMediaSample_GetPointer(This
->renderer
.pMediaSample
, (BYTE
**)&ptr
);
483 memcpy((char *)pDIBImage
+ bmiHeader
->biSize
, ptr
, IMediaSample_GetActualDataLength(This
->renderer
.pMediaSample
));
485 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
489 static HRESULT WINAPI
VideoRenderer_GetTargetRect(BaseControlVideo
* iface
, RECT
*pTargetRect
)
491 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
492 CopyRect(pTargetRect
,&This
->DestRect
);
496 static VIDEOINFOHEADER
* WINAPI
VideoRenderer_GetVideoFormat(BaseControlVideo
* iface
)
498 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
501 TRACE("(%p/%p)\n", This
, iface
);
503 pmt
= &This
->renderer
.sink
.pin
.mtCurrent
;
504 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
505 return (VIDEOINFOHEADER
*)pmt
->pbFormat
;
506 } else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
)) {
507 static VIDEOINFOHEADER vih
;
508 VIDEOINFOHEADER2
*vih2
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
509 memcpy(&vih
,vih2
,sizeof(VIDEOINFOHEADER
));
510 memcpy(&vih
.bmiHeader
, &vih2
->bmiHeader
, sizeof(BITMAPINFOHEADER
));
513 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt
->formattype
));
518 static HRESULT WINAPI
VideoRenderer_IsDefaultSourceRect(BaseControlVideo
* iface
)
520 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
521 FIXME("(%p/%p)->(): stub !!!\n", This
, iface
);
526 static HRESULT WINAPI
VideoRenderer_IsDefaultTargetRect(BaseControlVideo
* iface
)
528 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
529 FIXME("(%p/%p)->(): stub !!!\n", This
, iface
);
534 static HRESULT WINAPI
VideoRenderer_SetDefaultSourceRect(BaseControlVideo
* iface
)
536 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
538 SetRect(&This
->SourceRect
, 0, 0, This
->VideoWidth
, This
->VideoHeight
);
543 static HRESULT WINAPI
VideoRenderer_SetDefaultTargetRect(BaseControlVideo
* iface
)
545 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
548 if (!GetClientRect(This
->baseControlWindow
.baseWindow
.hWnd
, &rect
))
551 SetRect(&This
->DestRect
, 0, 0, rect
.right
, rect
.bottom
);
556 static HRESULT WINAPI
VideoRenderer_SetSourceRect(BaseControlVideo
* iface
, RECT
*pSourceRect
)
558 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
559 CopyRect(&This
->SourceRect
,pSourceRect
);
563 static HRESULT WINAPI
VideoRenderer_SetTargetRect(BaseControlVideo
* iface
, RECT
*pTargetRect
)
565 VideoRendererImpl
*This
= impl_from_BaseControlVideo(iface
);
566 CopyRect(&This
->DestRect
,pTargetRect
);
570 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable
= {
571 VideoRenderer_GetSourceRect
,
572 VideoRenderer_GetStaticImage
,
573 VideoRenderer_GetTargetRect
,
574 VideoRenderer_GetVideoFormat
,
575 VideoRenderer_IsDefaultSourceRect
,
576 VideoRenderer_IsDefaultTargetRect
,
577 VideoRenderer_SetDefaultSourceRect
,
578 VideoRenderer_SetDefaultTargetRect
,
579 VideoRenderer_SetSourceRect
,
580 VideoRenderer_SetTargetRect
583 /** IMediaFilter methods **/
585 static HRESULT WINAPI
VideoRenderer_Pause(IBaseFilter
* iface
)
587 VideoRendererImpl
*This
= impl_from_IBaseFilter(iface
);
589 TRACE("(%p/%p)->()\n", This
, iface
);
591 EnterCriticalSection(&This
->renderer
.csRenderLock
);
592 if (This
->renderer
.filter
.state
!= State_Paused
)
594 if (This
->renderer
.filter
.state
== State_Stopped
)
596 This
->renderer
.sink
.end_of_stream
= 0;
597 ResetEvent(This
->hEvent
);
598 VideoRenderer_AutoShowWindow(This
);
601 ResetEvent(This
->renderer
.flush_event
);
602 This
->renderer
.filter
.state
= State_Paused
;
604 LeaveCriticalSection(&This
->renderer
.csRenderLock
);
609 static const IBaseFilterVtbl VideoRenderer_Vtbl
=
611 BaseFilterImpl_QueryInterface
,
612 BaseFilterImpl_AddRef
,
613 BaseFilterImpl_Release
,
614 BaseFilterImpl_GetClassID
,
615 BaseRendererImpl_Stop
,
617 BaseRendererImpl_Run
,
618 BaseRendererImpl_GetState
,
619 BaseRendererImpl_SetSyncSource
,
620 BaseFilterImpl_GetSyncSource
,
621 BaseFilterImpl_EnumPins
,
622 BaseFilterImpl_FindPin
,
623 BaseFilterImpl_QueryFilterInfo
,
624 BaseFilterImpl_JoinFilterGraph
,
625 BaseFilterImpl_QueryVendorInfo
628 static HRESULT WINAPI
VideoWindow_get_FullScreenMode(IVideoWindow
*iface
,
629 LONG
*FullScreenMode
)
631 VideoRendererImpl
*This
= impl_from_IVideoWindow(iface
);
633 TRACE("(%p/%p)->(%p): %d\n", This
, iface
, FullScreenMode
, This
->FullScreenMode
);
638 *FullScreenMode
= This
->FullScreenMode
;
643 static HRESULT WINAPI
VideoWindow_put_FullScreenMode(IVideoWindow
*iface
,
646 VideoRendererImpl
*This
= impl_from_IVideoWindow(iface
);
648 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, FullScreenMode
);
650 if (FullScreenMode
) {
651 This
->saved_style
= GetWindowLongW(This
->baseControlWindow
.baseWindow
.hWnd
, GWL_STYLE
);
652 ShowWindow(This
->baseControlWindow
.baseWindow
.hWnd
, SW_HIDE
);
653 SetParent(This
->baseControlWindow
.baseWindow
.hWnd
, 0);
654 SetWindowLongW(This
->baseControlWindow
.baseWindow
.hWnd
, GWL_STYLE
, WS_POPUP
);
655 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
,HWND_TOP
,0,0,GetSystemMetrics(SM_CXSCREEN
),GetSystemMetrics(SM_CYSCREEN
),SWP_SHOWWINDOW
);
656 GetWindowRect(This
->baseControlWindow
.baseWindow
.hWnd
, &This
->DestRect
);
657 This
->WindowPos
= This
->DestRect
;
659 ShowWindow(This
->baseControlWindow
.baseWindow
.hWnd
, SW_HIDE
);
660 SetParent(This
->baseControlWindow
.baseWindow
.hWnd
, This
->baseControlWindow
.hwndOwner
);
661 SetWindowLongW(This
->baseControlWindow
.baseWindow
.hWnd
, GWL_STYLE
, This
->saved_style
);
662 GetClientRect(This
->baseControlWindow
.baseWindow
.hWnd
, &This
->DestRect
);
663 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
,0,This
->DestRect
.left
,This
->DestRect
.top
,This
->DestRect
.right
,This
->DestRect
.bottom
,SWP_NOZORDER
|SWP_SHOWWINDOW
);
664 This
->WindowPos
= This
->DestRect
;
666 This
->FullScreenMode
= FullScreenMode
;
671 static const IVideoWindowVtbl IVideoWindow_VTable
=
673 BaseControlWindowImpl_QueryInterface
,
674 BaseControlWindowImpl_AddRef
,
675 BaseControlWindowImpl_Release
,
676 BaseControlWindowImpl_GetTypeInfoCount
,
677 BaseControlWindowImpl_GetTypeInfo
,
678 BaseControlWindowImpl_GetIDsOfNames
,
679 BaseControlWindowImpl_Invoke
,
680 BaseControlWindowImpl_put_Caption
,
681 BaseControlWindowImpl_get_Caption
,
682 BaseControlWindowImpl_put_WindowStyle
,
683 BaseControlWindowImpl_get_WindowStyle
,
684 BaseControlWindowImpl_put_WindowStyleEx
,
685 BaseControlWindowImpl_get_WindowStyleEx
,
686 BaseControlWindowImpl_put_AutoShow
,
687 BaseControlWindowImpl_get_AutoShow
,
688 BaseControlWindowImpl_put_WindowState
,
689 BaseControlWindowImpl_get_WindowState
,
690 BaseControlWindowImpl_put_BackgroundPalette
,
691 BaseControlWindowImpl_get_BackgroundPalette
,
692 BaseControlWindowImpl_put_Visible
,
693 BaseControlWindowImpl_get_Visible
,
694 BaseControlWindowImpl_put_Left
,
695 BaseControlWindowImpl_get_Left
,
696 BaseControlWindowImpl_put_Width
,
697 BaseControlWindowImpl_get_Width
,
698 BaseControlWindowImpl_put_Top
,
699 BaseControlWindowImpl_get_Top
,
700 BaseControlWindowImpl_put_Height
,
701 BaseControlWindowImpl_get_Height
,
702 BaseControlWindowImpl_put_Owner
,
703 BaseControlWindowImpl_get_Owner
,
704 BaseControlWindowImpl_put_MessageDrain
,
705 BaseControlWindowImpl_get_MessageDrain
,
706 BaseControlWindowImpl_get_BorderColor
,
707 BaseControlWindowImpl_put_BorderColor
,
708 VideoWindow_get_FullScreenMode
,
709 VideoWindow_put_FullScreenMode
,
710 BaseControlWindowImpl_SetWindowForeground
,
711 BaseControlWindowImpl_NotifyOwnerMessage
,
712 BaseControlWindowImpl_SetWindowPosition
,
713 BaseControlWindowImpl_GetWindowPosition
,
714 BaseControlWindowImpl_GetMinIdealImageSize
,
715 BaseControlWindowImpl_GetMaxIdealImageSize
,
716 BaseControlWindowImpl_GetRestorePosition
,
717 BaseControlWindowImpl_HideCursor
,
718 BaseControlWindowImpl_IsCursorHidden
721 static inline VideoRendererImpl
*impl_from_IOverlay(IOverlay
*iface
)
723 return CONTAINING_RECORD(iface
, VideoRendererImpl
, IOverlay_iface
);
726 static HRESULT WINAPI
overlay_QueryInterface(IOverlay
*iface
, REFIID iid
, void **out
)
728 VideoRendererImpl
*filter
= impl_from_IOverlay(iface
);
729 return IPin_QueryInterface(&filter
->renderer
.sink
.pin
.IPin_iface
, iid
, out
);
732 static ULONG WINAPI
overlay_AddRef(IOverlay
*iface
)
734 VideoRendererImpl
*filter
= impl_from_IOverlay(iface
);
735 return IPin_AddRef(&filter
->renderer
.sink
.pin
.IPin_iface
);
738 static ULONG WINAPI
overlay_Release(IOverlay
*iface
)
740 VideoRendererImpl
*filter
= impl_from_IOverlay(iface
);
741 return IPin_Release(&filter
->renderer
.sink
.pin
.IPin_iface
);
744 static HRESULT WINAPI
overlay_GetPalette(IOverlay
*iface
, DWORD
*count
, PALETTEENTRY
**palette
)
746 FIXME("iface %p, count %p, palette %p, stub!\n", iface
, count
, palette
);
750 static HRESULT WINAPI
overlay_SetPalette(IOverlay
*iface
, DWORD count
, PALETTEENTRY
*palette
)
752 FIXME("iface %p, count %u, palette %p, stub!\n", iface
, count
, palette
);
756 static HRESULT WINAPI
overlay_GetDefaultColorKey(IOverlay
*iface
, COLORKEY
*key
)
758 FIXME("iface %p, key %p, stub!\n", iface
, key
);
762 static HRESULT WINAPI
overlay_GetColorKey(IOverlay
*iface
, COLORKEY
*key
)
764 FIXME("iface %p, key %p, stub!\n", iface
, key
);
768 static HRESULT WINAPI
overlay_SetColorKey(IOverlay
*iface
, COLORKEY
*key
)
770 FIXME("iface %p, key %p, stub!\n", iface
, key
);
774 static HRESULT WINAPI
overlay_GetWindowHandle(IOverlay
*iface
, HWND
*window
)
776 VideoRendererImpl
*filter
= impl_from_IOverlay(iface
);
778 TRACE("filter %p, window %p.\n", filter
, window
);
780 *window
= filter
->baseControlWindow
.baseWindow
.hWnd
;
784 static HRESULT WINAPI
overlay_GetClipList(IOverlay
*iface
, RECT
*source
, RECT
*dest
, RGNDATA
**region
)
786 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface
, source
, dest
, region
);
790 static HRESULT WINAPI
overlay_GetVideoPosition(IOverlay
*iface
, RECT
*source
, RECT
*dest
)
792 FIXME("iface %p, source %p, dest %p, stub!\n", iface
, source
, dest
);
796 static HRESULT WINAPI
overlay_Advise(IOverlay
*iface
, IOverlayNotify
*sink
, DWORD flags
)
798 FIXME("iface %p, sink %p, flags %#x, stub!\n", iface
, sink
, flags
);
802 static HRESULT WINAPI
overlay_Unadvise(IOverlay
*iface
)
804 FIXME("iface %p, stub!\n", iface
);
808 static const IOverlayVtbl overlay_vtbl
=
810 overlay_QueryInterface
,
815 overlay_GetDefaultColorKey
,
818 overlay_GetWindowHandle
,
820 overlay_GetVideoPosition
,
825 HRESULT
VideoRenderer_create(IUnknown
*outer
, void **out
)
827 static const WCHAR sink_name
[] = {'I','n',0};
829 VideoRendererImpl
* pVideoRenderer
;
833 pVideoRenderer
= CoTaskMemAlloc(sizeof(VideoRendererImpl
));
835 pVideoRenderer
->init
= FALSE
;
836 ZeroMemory(&pVideoRenderer
->SourceRect
, sizeof(RECT
));
837 ZeroMemory(&pVideoRenderer
->DestRect
, sizeof(RECT
));
838 ZeroMemory(&pVideoRenderer
->WindowPos
, sizeof(RECT
));
839 pVideoRenderer
->FullScreenMode
= OAFALSE
;
841 pVideoRenderer
->IOverlay_iface
.lpVtbl
= &overlay_vtbl
;
843 hr
= strmbase_renderer_init(&pVideoRenderer
->renderer
, &VideoRenderer_Vtbl
,
844 outer
, &CLSID_VideoRenderer
, sink_name
, &BaseFuncTable
);
849 hr
= BaseControlWindow_Init(&pVideoRenderer
->baseControlWindow
, &IVideoWindow_VTable
,
850 &pVideoRenderer
->renderer
.filter
, &pVideoRenderer
->renderer
.filter
.csFilter
,
851 &pVideoRenderer
->renderer
.sink
.pin
, &renderer_BaseWindowFuncTable
);
855 hr
= strmbase_video_init(&pVideoRenderer
->baseControlVideo
,
856 &pVideoRenderer
->renderer
.filter
, &pVideoRenderer
->renderer
.filter
.csFilter
,
857 &pVideoRenderer
->renderer
.sink
.pin
, &renderer_BaseControlVideoFuncTable
);
861 pVideoRenderer
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
863 if (FAILED(hr
= BaseWindowImpl_PrepareWindow(&pVideoRenderer
->baseControlWindow
.baseWindow
)))
865 CloseHandle(pVideoRenderer
->hEvent
);
869 *out
= &pVideoRenderer
->renderer
.filter
.IUnknown_inner
;
873 strmbase_renderer_cleanup(&pVideoRenderer
->renderer
);
874 CoTaskMemFree(pVideoRenderer
);
878 HRESULT
VideoRendererDefault_create(IUnknown
* pUnkOuter
, LPVOID
* ppv
)
880 /* TODO: Attempt to use the VMR-7 renderer instead when possible */
881 return VideoRenderer_create(pUnkOuter
, ppv
);