quartz/videorenderer: Get rid of CreateRenderingSubsystem().
[wine.git] / dlls / quartz / videorenderer.c
blobdb5ee0fbf4ac6d3e6dd6476673aa83acaf9c478f
1 /*
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"
23 #include "uuids.h"
24 #include "vfwmsgs.h"
25 #include "amvideo.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "dshow.h"
29 #include "evcode.h"
30 #include "strmif.h"
31 #include "ddraw.h"
32 #include "dvdmedia.h"
34 #include <assert.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;
47 BOOL init;
49 HANDLE hEvent;
50 RECT SourceRect;
51 RECT DestRect;
52 RECT WindowPos;
53 LONG VideoWidth;
54 LONG VideoHeight;
55 LONG FullScreenMode;
57 DWORD saved_style;
58 } VideoRendererImpl;
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;
99 else
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;
112 else
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,
124 This->WindowPos.top,
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;
133 This->init = TRUE;
134 if (This->baseControlWindow.AutoShow)
135 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
138 static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
140 AM_MEDIA_TYPE amt;
141 HRESULT hr = S_OK;
142 BITMAPINFOHEADER *bmiHeader;
143 HDC dc;
145 TRACE("(%p)->(%p, %d)\n", This, data, size);
147 hr = IPin_ConnectionMediaType(&This->renderer.sink.pin.IPin_iface, &amt);
148 if (FAILED(hr)) {
149 ERR("Unable to retrieve media type\n");
150 return hr;
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;
161 else
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);
177 return S_OK;
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)
184 return E_FAIL;
185 return S_FALSE;
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;
193 HRESULT hr;
195 TRACE("(%p)->(%p)\n", This, pSample);
197 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
198 if (FAILED(hr))
200 ERR("Cannot get pointer to sample data (%x)\n", hr);
201 return hr;
204 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
206 TRACE("val %p %d\n", pbSrcStream, cbSrcStream);
208 #if 0 /* For debugging purpose */
210 int i;
211 for(i = 0; i < cbSrcStream; i++)
213 if ((i!=0) && !(i%16))
214 TRACE("\n");
215 TRACE("%02x ", pbSrcStream[i]);
217 TRACE("\n");
219 #endif
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)
228 /* Flushing */
229 return S_OK;
231 if (This->renderer.filter.state == State_Stopped)
233 return VFW_E_WRONG_STATE;
235 } else {
236 VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
238 return S_OK;
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))
246 return S_FALSE;
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))
253 LONG height;
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;
262 if (height < 0)
263 This->SourceRect.bottom = This->VideoHeight = -height;
264 else
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;
275 if (height < 0)
276 This->SourceRect.bottom = This->VideoHeight = -height;
277 else
278 This->SourceRect.bottom = This->VideoHeight = height;
280 else
282 WARN("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
283 return S_FALSE;
285 return S_OK;
287 return S_FALSE;
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;
331 else
332 return E_NOINTERFACE;
334 IUnknown_AddRef((IUnknown *)*out);
335 return S_OK;
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;
344 else
345 return E_NOINTERFACE;
347 IUnknown_AddRef((IUnknown *)*out);
348 return S_OK;
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)
359 /* Black it out */
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);
383 static RECT defRect;
385 SetRect(&defRect, 0, 0, This->VideoWidth, This->VideoHeight);
387 return defRect;
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",
397 This->DestRect.left,
398 This->DestRect.top,
399 This->DestRect.right - This->DestRect.left,
400 This->DestRect.bottom - This->DestRect.top);
402 return TRUE;
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,
420 VideoRenderer_OnSize
423 static HRESULT WINAPI VideoRenderer_GetSourceRect(BaseControlVideo* iface, RECT *pSourceRect)
425 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
426 CopyRect(pSourceRect,&This->SourceRect);
427 return S_OK;
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;
435 LONG needed_size;
436 char *ptr;
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;
456 else
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);
466 if (!pDIBImage)
468 *pBufferSize = needed_size;
469 LeaveCriticalSection(&This->renderer.filter.csFilter);
470 return S_OK;
473 if (needed_size < *pBufferSize)
475 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
476 LeaveCriticalSection(&This->renderer.filter.csFilter);
477 return E_FAIL;
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);
486 return S_OK;
489 static HRESULT WINAPI VideoRenderer_GetTargetRect(BaseControlVideo* iface, RECT *pTargetRect)
491 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
492 CopyRect(pTargetRect,&This->DestRect);
493 return S_OK;
496 static VIDEOINFOHEADER* WINAPI VideoRenderer_GetVideoFormat(BaseControlVideo* iface)
498 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
499 AM_MEDIA_TYPE *pmt;
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));
511 return &vih;
512 } else {
513 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
514 return NULL;
518 static HRESULT WINAPI VideoRenderer_IsDefaultSourceRect(BaseControlVideo* iface)
520 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
521 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
523 return S_OK;
526 static HRESULT WINAPI VideoRenderer_IsDefaultTargetRect(BaseControlVideo* iface)
528 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
529 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
531 return S_OK;
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);
540 return S_OK;
543 static HRESULT WINAPI VideoRenderer_SetDefaultTargetRect(BaseControlVideo* iface)
545 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
546 RECT rect;
548 if (!GetClientRect(This->baseControlWindow.baseWindow.hWnd, &rect))
549 return E_FAIL;
551 SetRect(&This->DestRect, 0, 0, rect.right, rect.bottom);
553 return S_OK;
556 static HRESULT WINAPI VideoRenderer_SetSourceRect(BaseControlVideo* iface, RECT *pSourceRect)
558 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
559 CopyRect(&This->SourceRect,pSourceRect);
560 return S_OK;
563 static HRESULT WINAPI VideoRenderer_SetTargetRect(BaseControlVideo* iface, RECT *pTargetRect)
565 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
566 CopyRect(&This->DestRect,pTargetRect);
567 return S_OK;
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);
606 return S_OK;
609 static const IBaseFilterVtbl VideoRenderer_Vtbl =
611 BaseFilterImpl_QueryInterface,
612 BaseFilterImpl_AddRef,
613 BaseFilterImpl_Release,
614 BaseFilterImpl_GetClassID,
615 BaseRendererImpl_Stop,
616 VideoRenderer_Pause,
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);
635 if (!FullScreenMode)
636 return E_POINTER;
638 *FullScreenMode = This->FullScreenMode;
640 return S_OK;
643 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
644 LONG FullScreenMode)
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;
658 } else {
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;
668 return S_OK;
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);
747 return E_NOTIMPL;
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);
753 return E_NOTIMPL;
756 static HRESULT WINAPI overlay_GetDefaultColorKey(IOverlay *iface, COLORKEY *key)
758 FIXME("iface %p, key %p, stub!\n", iface, key);
759 return E_NOTIMPL;
762 static HRESULT WINAPI overlay_GetColorKey(IOverlay *iface, COLORKEY *key)
764 FIXME("iface %p, key %p, stub!\n", iface, key);
765 return E_NOTIMPL;
768 static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key)
770 FIXME("iface %p, key %p, stub!\n", iface, key);
771 return E_NOTIMPL;
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;
781 return S_OK;
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);
787 return E_NOTIMPL;
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);
793 return E_NOTIMPL;
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);
799 return E_NOTIMPL;
802 static HRESULT WINAPI overlay_Unadvise(IOverlay *iface)
804 FIXME("iface %p, stub!\n", iface);
805 return E_NOTIMPL;
808 static const IOverlayVtbl overlay_vtbl =
810 overlay_QueryInterface,
811 overlay_AddRef,
812 overlay_Release,
813 overlay_GetPalette,
814 overlay_SetPalette,
815 overlay_GetDefaultColorKey,
816 overlay_GetColorKey,
817 overlay_SetColorKey,
818 overlay_GetWindowHandle,
819 overlay_GetClipList,
820 overlay_GetVideoPosition,
821 overlay_Advise,
822 overlay_Unadvise,
825 HRESULT VideoRenderer_create(IUnknown *outer, void **out)
827 static const WCHAR sink_name[] = {'I','n',0};
828 HRESULT hr;
829 VideoRendererImpl * pVideoRenderer;
831 *out = NULL;
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);
846 if (FAILED(hr))
847 goto fail;
849 hr = BaseControlWindow_Init(&pVideoRenderer->baseControlWindow, &IVideoWindow_VTable,
850 &pVideoRenderer->renderer.filter, &pVideoRenderer->renderer.filter.csFilter,
851 &pVideoRenderer->renderer.sink.pin, &renderer_BaseWindowFuncTable);
852 if (FAILED(hr))
853 goto fail;
855 hr = strmbase_video_init(&pVideoRenderer->baseControlVideo,
856 &pVideoRenderer->renderer.filter, &pVideoRenderer->renderer.filter.csFilter,
857 &pVideoRenderer->renderer.sink.pin, &renderer_BaseControlVideoFuncTable);
858 if (FAILED(hr))
859 goto fail;
861 pVideoRenderer->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
863 if (FAILED(hr = BaseWindowImpl_PrepareWindow(&pVideoRenderer->baseControlWindow.baseWindow)))
865 CloseHandle(pVideoRenderer->hEvent);
866 goto fail;
869 *out = &pVideoRenderer->renderer.filter.IUnknown_inner;
870 return S_OK;
872 fail:
873 strmbase_renderer_cleanup(&pVideoRenderer->renderer);
874 CoTaskMemFree(pVideoRenderer);
875 return hr;
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);