mfplat: Make functionality of GetMediaTypeHandler more clear.
[wine.git] / dlls / quartz / videorenderer.c
blobe634a92fbe4b9fc50557082b82b4ca613896d690
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 struct strmbase_renderer renderer;
42 BaseControlWindow baseControlWindow;
43 BaseControlVideo baseControlVideo;
45 IOverlay IOverlay_iface;
47 BOOL init;
49 RECT SourceRect;
50 RECT DestRect;
51 RECT WindowPos;
52 LONG VideoWidth;
53 LONG VideoHeight;
54 LONG FullScreenMode;
56 DWORD saved_style;
58 HANDLE run_event;
59 } VideoRendererImpl;
61 static inline VideoRendererImpl *impl_from_BaseWindow(BaseWindow *iface)
63 return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlWindow.baseWindow);
66 static inline VideoRendererImpl *impl_from_strmbase_renderer(struct strmbase_renderer *iface)
68 return CONTAINING_RECORD(iface, VideoRendererImpl, renderer);
71 static inline VideoRendererImpl *impl_from_IBaseFilter(IBaseFilter *iface)
73 return CONTAINING_RECORD(iface, VideoRendererImpl, renderer.filter.IBaseFilter_iface);
76 static inline VideoRendererImpl *impl_from_IVideoWindow(IVideoWindow *iface)
78 return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlWindow.IVideoWindow_iface);
81 static inline VideoRendererImpl *impl_from_BaseControlVideo(BaseControlVideo *iface)
83 return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlVideo);
86 static void VideoRenderer_AutoShowWindow(VideoRendererImpl *This)
88 if (!This->init && (!This->WindowPos.right || !This->WindowPos.top))
90 DWORD style = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE);
91 DWORD style_ex = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_EXSTYLE);
93 if (!This->WindowPos.right)
95 if (This->DestRect.right)
97 This->WindowPos.left = This->DestRect.left;
98 This->WindowPos.right = This->DestRect.right;
100 else
102 This->WindowPos.left = This->SourceRect.left;
103 This->WindowPos.right = This->SourceRect.right;
106 if (!This->WindowPos.bottom)
108 if (This->DestRect.bottom)
110 This->WindowPos.top = This->DestRect.top;
111 This->WindowPos.bottom = This->DestRect.bottom;
113 else
115 This->WindowPos.top = This->SourceRect.top;
116 This->WindowPos.bottom = This->SourceRect.bottom;
120 AdjustWindowRectEx(&This->WindowPos, style, FALSE, style_ex);
122 TRACE("WindowPos: %s\n", wine_dbgstr_rect(&This->WindowPos));
123 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
124 This->WindowPos.left,
125 This->WindowPos.top,
126 This->WindowPos.right - This->WindowPos.left,
127 This->WindowPos.bottom - This->WindowPos.top,
128 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
130 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect);
132 else if (!This->init)
133 This->DestRect = This->WindowPos;
134 This->init = TRUE;
135 if (This->baseControlWindow.AutoShow)
136 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
139 static HRESULT WINAPI VideoRenderer_ShouldDrawSampleNow(struct strmbase_renderer *filter,
140 IMediaSample *pSample, REFERENCE_TIME *start, REFERENCE_TIME *end)
142 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
143 if (IMediaSample_IsPreroll(pSample) == S_OK)
144 return E_FAIL;
145 return S_FALSE;
148 static HRESULT WINAPI VideoRenderer_DoRenderSample(struct strmbase_renderer *iface, IMediaSample *pSample)
150 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
151 const AM_MEDIA_TYPE *mt = &filter->renderer.sink.pin.mt;
152 LPBYTE pbSrcStream = NULL;
153 BITMAPINFOHEADER *bih;
154 HRESULT hr;
155 HDC dc;
157 TRACE("filter %p, sample %p.\n", filter, pSample);
159 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
160 if (FAILED(hr))
162 ERR("Cannot get pointer to sample data (%x)\n", hr);
163 return hr;
166 if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
167 bih = &((VIDEOINFOHEADER *)mt->pbFormat)->bmiHeader;
168 else
169 bih = &((VIDEOINFOHEADER2 *)mt->pbFormat)->bmiHeader;
171 dc = GetDC(filter->baseControlWindow.baseWindow.hWnd);
172 StretchDIBits(dc, filter->DestRect.left, filter->DestRect.top,
173 filter->DestRect.right - filter->DestRect.left,
174 filter->DestRect.bottom - filter->DestRect.top,
175 filter->SourceRect.left, filter->SourceRect.top,
176 filter->SourceRect.right - filter->SourceRect.left,
177 filter->SourceRect.bottom - filter->SourceRect.top,
178 pbSrcStream, (BITMAPINFO *)bih, DIB_RGB_COLORS, SRCCOPY);
179 ReleaseDC(filter->baseControlWindow.baseWindow.hWnd, dc);
181 if (filter->renderer.filter.state == State_Paused)
183 const HANDLE events[2] = {filter->run_event, filter->renderer.flush_event};
185 LeaveCriticalSection(&filter->renderer.csRenderLock);
186 WaitForMultipleObjects(2, events, FALSE, INFINITE);
187 EnterCriticalSection(&filter->renderer.csRenderLock);
190 return S_OK;
193 static HRESULT WINAPI VideoRenderer_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *pmt)
195 VideoRendererImpl *This = impl_from_strmbase_renderer(iface);
197 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video))
198 return S_FALSE;
200 if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32) ||
201 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24) ||
202 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565) ||
203 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8))
205 LONG height;
207 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
209 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
210 This->SourceRect.left = 0;
211 This->SourceRect.top = 0;
212 This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth;
213 height = format->bmiHeader.biHeight;
214 if (height < 0)
215 This->SourceRect.bottom = This->VideoHeight = -height;
216 else
217 This->SourceRect.bottom = This->VideoHeight = height;
219 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
221 VIDEOINFOHEADER2 *format2 = (VIDEOINFOHEADER2 *)pmt->pbFormat;
223 This->SourceRect.left = 0;
224 This->SourceRect.top = 0;
225 This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth;
226 height = format2->bmiHeader.biHeight;
227 if (height < 0)
228 This->SourceRect.bottom = This->VideoHeight = -height;
229 else
230 This->SourceRect.bottom = This->VideoHeight = height;
232 else
234 WARN("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
235 return S_FALSE;
237 return S_OK;
239 return S_FALSE;
242 static void video_renderer_destroy(struct strmbase_renderer *iface)
244 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
246 BaseControlWindow_Destroy(&filter->baseControlWindow);
247 BaseControlVideo_Destroy(&filter->baseControlVideo);
248 CloseHandle(filter->run_event);
249 strmbase_renderer_cleanup(&filter->renderer);
250 CoTaskMemFree(filter);
253 static HRESULT video_renderer_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
255 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
257 if (IsEqualGUID(iid, &IID_IBasicVideo))
258 *out = &filter->baseControlVideo.IBasicVideo_iface;
259 else if (IsEqualGUID(iid, &IID_IVideoWindow))
260 *out = &filter->baseControlWindow.IVideoWindow_iface;
261 else
262 return E_NOINTERFACE;
264 IUnknown_AddRef((IUnknown *)*out);
265 return S_OK;
268 static HRESULT video_renderer_pin_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
270 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
272 if (IsEqualGUID(iid, &IID_IOverlay))
273 *out = &filter->IOverlay_iface;
274 else
275 return E_NOINTERFACE;
277 IUnknown_AddRef((IUnknown *)*out);
278 return S_OK;
281 static void video_renderer_start_stream(struct strmbase_renderer *iface)
283 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
285 SetEvent(filter->run_event);
288 static void video_renderer_stop_stream(struct strmbase_renderer *iface)
290 VideoRendererImpl *This = impl_from_strmbase_renderer(iface);
292 TRACE("(%p)->()\n", This);
294 if (This->baseControlWindow.AutoShow)
295 /* Black it out */
296 RedrawWindow(This->baseControlWindow.baseWindow.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE);
298 ResetEvent(This->run_event);
301 static void video_renderer_init_stream(struct strmbase_renderer *iface)
303 VideoRendererImpl *filter = impl_from_strmbase_renderer(iface);
305 VideoRenderer_AutoShowWindow(filter);
308 static RECT WINAPI VideoRenderer_GetDefaultRect(BaseWindow *iface)
310 VideoRendererImpl *This = impl_from_BaseWindow(iface);
311 static RECT defRect;
313 SetRect(&defRect, 0, 0, This->VideoWidth, This->VideoHeight);
315 return defRect;
318 static BOOL WINAPI VideoRenderer_OnSize(BaseWindow *iface, LONG Width, LONG Height)
320 VideoRendererImpl *This = impl_from_BaseWindow(iface);
322 TRACE("WM_SIZE %d %d\n", Width, Height);
323 GetClientRect(iface->hWnd, &This->DestRect);
324 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
325 This->DestRect.left,
326 This->DestRect.top,
327 This->DestRect.right - This->DestRect.left,
328 This->DestRect.bottom - This->DestRect.top);
330 return TRUE;
333 static const struct strmbase_renderer_ops renderer_ops =
335 .pfnCheckMediaType = VideoRenderer_CheckMediaType,
336 .pfnDoRenderSample = VideoRenderer_DoRenderSample,
337 .renderer_init_stream = video_renderer_init_stream,
338 .renderer_start_stream = video_renderer_start_stream,
339 .renderer_stop_stream = video_renderer_stop_stream,
340 .pfnShouldDrawSampleNow = VideoRenderer_ShouldDrawSampleNow,
341 .renderer_destroy = video_renderer_destroy,
342 .renderer_query_interface = video_renderer_query_interface,
343 .renderer_pin_query_interface = video_renderer_pin_query_interface,
346 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
347 VideoRenderer_GetDefaultRect,
348 VideoRenderer_OnSize
351 static HRESULT WINAPI VideoRenderer_GetSourceRect(BaseControlVideo* iface, RECT *pSourceRect)
353 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
354 CopyRect(pSourceRect,&This->SourceRect);
355 return S_OK;
358 static HRESULT WINAPI VideoRenderer_GetStaticImage(BaseControlVideo* iface, LONG *pBufferSize, LONG *pDIBImage)
360 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
361 AM_MEDIA_TYPE *amt = &This->renderer.sink.pin.mt;
362 BITMAPINFOHEADER *bmiHeader;
363 LONG needed_size;
364 char *ptr;
366 FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage);
368 EnterCriticalSection(&This->renderer.filter.csFilter);
370 if (!This->renderer.pMediaSample)
372 LeaveCriticalSection(&This->renderer.filter.csFilter);
373 return (This->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
376 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
378 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
380 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
382 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
384 else
386 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
387 LeaveCriticalSection(&This->renderer.filter.csFilter);
388 return VFW_E_RUNTIME_ERROR;
391 needed_size = bmiHeader->biSize;
392 needed_size += IMediaSample_GetActualDataLength(This->renderer.pMediaSample);
394 if (!pDIBImage)
396 *pBufferSize = needed_size;
397 LeaveCriticalSection(&This->renderer.filter.csFilter);
398 return S_OK;
401 if (needed_size < *pBufferSize)
403 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
404 LeaveCriticalSection(&This->renderer.filter.csFilter);
405 return E_FAIL;
407 *pBufferSize = needed_size;
409 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
410 IMediaSample_GetPointer(This->renderer.pMediaSample, (BYTE **)&ptr);
411 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->renderer.pMediaSample));
413 LeaveCriticalSection(&This->renderer.filter.csFilter);
414 return S_OK;
417 static HRESULT WINAPI VideoRenderer_GetTargetRect(BaseControlVideo* iface, RECT *pTargetRect)
419 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
420 CopyRect(pTargetRect,&This->DestRect);
421 return S_OK;
424 static VIDEOINFOHEADER* WINAPI VideoRenderer_GetVideoFormat(BaseControlVideo* iface)
426 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
427 AM_MEDIA_TYPE *pmt;
429 TRACE("(%p/%p)\n", This, iface);
431 pmt = &This->renderer.sink.pin.mt;
432 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
433 return (VIDEOINFOHEADER*)pmt->pbFormat;
434 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
435 static VIDEOINFOHEADER vih;
436 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
437 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
438 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
439 return &vih;
440 } else {
441 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
442 return NULL;
446 static HRESULT WINAPI VideoRenderer_IsDefaultSourceRect(BaseControlVideo* iface)
448 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
449 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
451 return S_OK;
454 static HRESULT WINAPI VideoRenderer_IsDefaultTargetRect(BaseControlVideo* iface)
456 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
457 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
459 return S_OK;
462 static HRESULT WINAPI VideoRenderer_SetDefaultSourceRect(BaseControlVideo* iface)
464 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
466 SetRect(&This->SourceRect, 0, 0, This->VideoWidth, This->VideoHeight);
468 return S_OK;
471 static HRESULT WINAPI VideoRenderer_SetDefaultTargetRect(BaseControlVideo* iface)
473 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
474 RECT rect;
476 if (!GetClientRect(This->baseControlWindow.baseWindow.hWnd, &rect))
477 return E_FAIL;
479 SetRect(&This->DestRect, 0, 0, rect.right, rect.bottom);
481 return S_OK;
484 static HRESULT WINAPI VideoRenderer_SetSourceRect(BaseControlVideo* iface, RECT *pSourceRect)
486 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
487 CopyRect(&This->SourceRect,pSourceRect);
488 return S_OK;
491 static HRESULT WINAPI VideoRenderer_SetTargetRect(BaseControlVideo* iface, RECT *pTargetRect)
493 VideoRendererImpl *This = impl_from_BaseControlVideo(iface);
494 CopyRect(&This->DestRect,pTargetRect);
495 return S_OK;
498 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
499 VideoRenderer_GetSourceRect,
500 VideoRenderer_GetStaticImage,
501 VideoRenderer_GetTargetRect,
502 VideoRenderer_GetVideoFormat,
503 VideoRenderer_IsDefaultSourceRect,
504 VideoRenderer_IsDefaultTargetRect,
505 VideoRenderer_SetDefaultSourceRect,
506 VideoRenderer_SetDefaultTargetRect,
507 VideoRenderer_SetSourceRect,
508 VideoRenderer_SetTargetRect
511 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
512 LONG *FullScreenMode)
514 VideoRendererImpl *This = impl_from_IVideoWindow(iface);
516 TRACE("(%p/%p)->(%p): %d\n", This, iface, FullScreenMode, This->FullScreenMode);
518 if (!FullScreenMode)
519 return E_POINTER;
521 *FullScreenMode = This->FullScreenMode;
523 return S_OK;
526 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
527 LONG FullScreenMode)
529 VideoRendererImpl *This = impl_from_IVideoWindow(iface);
531 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, FullScreenMode);
533 if (FullScreenMode) {
534 This->saved_style = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE);
535 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_HIDE);
536 SetParent(This->baseControlWindow.baseWindow.hWnd, 0);
537 SetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE, WS_POPUP);
538 SetWindowPos(This->baseControlWindow.baseWindow.hWnd,HWND_TOP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SWP_SHOWWINDOW);
539 GetWindowRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect);
540 This->WindowPos = This->DestRect;
541 } else {
542 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_HIDE);
543 SetParent(This->baseControlWindow.baseWindow.hWnd, This->baseControlWindow.hwndOwner);
544 SetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE, This->saved_style);
545 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect);
546 SetWindowPos(This->baseControlWindow.baseWindow.hWnd,0,This->DestRect.left,This->DestRect.top,This->DestRect.right,This->DestRect.bottom,SWP_NOZORDER|SWP_SHOWWINDOW);
547 This->WindowPos = This->DestRect;
549 This->FullScreenMode = FullScreenMode;
551 return S_OK;
554 static const IVideoWindowVtbl IVideoWindow_VTable =
556 BaseControlWindowImpl_QueryInterface,
557 BaseControlWindowImpl_AddRef,
558 BaseControlWindowImpl_Release,
559 BaseControlWindowImpl_GetTypeInfoCount,
560 BaseControlWindowImpl_GetTypeInfo,
561 BaseControlWindowImpl_GetIDsOfNames,
562 BaseControlWindowImpl_Invoke,
563 BaseControlWindowImpl_put_Caption,
564 BaseControlWindowImpl_get_Caption,
565 BaseControlWindowImpl_put_WindowStyle,
566 BaseControlWindowImpl_get_WindowStyle,
567 BaseControlWindowImpl_put_WindowStyleEx,
568 BaseControlWindowImpl_get_WindowStyleEx,
569 BaseControlWindowImpl_put_AutoShow,
570 BaseControlWindowImpl_get_AutoShow,
571 BaseControlWindowImpl_put_WindowState,
572 BaseControlWindowImpl_get_WindowState,
573 BaseControlWindowImpl_put_BackgroundPalette,
574 BaseControlWindowImpl_get_BackgroundPalette,
575 BaseControlWindowImpl_put_Visible,
576 BaseControlWindowImpl_get_Visible,
577 BaseControlWindowImpl_put_Left,
578 BaseControlWindowImpl_get_Left,
579 BaseControlWindowImpl_put_Width,
580 BaseControlWindowImpl_get_Width,
581 BaseControlWindowImpl_put_Top,
582 BaseControlWindowImpl_get_Top,
583 BaseControlWindowImpl_put_Height,
584 BaseControlWindowImpl_get_Height,
585 BaseControlWindowImpl_put_Owner,
586 BaseControlWindowImpl_get_Owner,
587 BaseControlWindowImpl_put_MessageDrain,
588 BaseControlWindowImpl_get_MessageDrain,
589 BaseControlWindowImpl_get_BorderColor,
590 BaseControlWindowImpl_put_BorderColor,
591 VideoWindow_get_FullScreenMode,
592 VideoWindow_put_FullScreenMode,
593 BaseControlWindowImpl_SetWindowForeground,
594 BaseControlWindowImpl_NotifyOwnerMessage,
595 BaseControlWindowImpl_SetWindowPosition,
596 BaseControlWindowImpl_GetWindowPosition,
597 BaseControlWindowImpl_GetMinIdealImageSize,
598 BaseControlWindowImpl_GetMaxIdealImageSize,
599 BaseControlWindowImpl_GetRestorePosition,
600 BaseControlWindowImpl_HideCursor,
601 BaseControlWindowImpl_IsCursorHidden
604 static inline VideoRendererImpl *impl_from_IOverlay(IOverlay *iface)
606 return CONTAINING_RECORD(iface, VideoRendererImpl, IOverlay_iface);
609 static HRESULT WINAPI overlay_QueryInterface(IOverlay *iface, REFIID iid, void **out)
611 VideoRendererImpl *filter = impl_from_IOverlay(iface);
612 return IPin_QueryInterface(&filter->renderer.sink.pin.IPin_iface, iid, out);
615 static ULONG WINAPI overlay_AddRef(IOverlay *iface)
617 VideoRendererImpl *filter = impl_from_IOverlay(iface);
618 return IPin_AddRef(&filter->renderer.sink.pin.IPin_iface);
621 static ULONG WINAPI overlay_Release(IOverlay *iface)
623 VideoRendererImpl *filter = impl_from_IOverlay(iface);
624 return IPin_Release(&filter->renderer.sink.pin.IPin_iface);
627 static HRESULT WINAPI overlay_GetPalette(IOverlay *iface, DWORD *count, PALETTEENTRY **palette)
629 FIXME("iface %p, count %p, palette %p, stub!\n", iface, count, palette);
630 return E_NOTIMPL;
633 static HRESULT WINAPI overlay_SetPalette(IOverlay *iface, DWORD count, PALETTEENTRY *palette)
635 FIXME("iface %p, count %u, palette %p, stub!\n", iface, count, palette);
636 return E_NOTIMPL;
639 static HRESULT WINAPI overlay_GetDefaultColorKey(IOverlay *iface, COLORKEY *key)
641 FIXME("iface %p, key %p, stub!\n", iface, key);
642 return E_NOTIMPL;
645 static HRESULT WINAPI overlay_GetColorKey(IOverlay *iface, COLORKEY *key)
647 FIXME("iface %p, key %p, stub!\n", iface, key);
648 return E_NOTIMPL;
651 static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key)
653 FIXME("iface %p, key %p, stub!\n", iface, key);
654 return E_NOTIMPL;
657 static HRESULT WINAPI overlay_GetWindowHandle(IOverlay *iface, HWND *window)
659 VideoRendererImpl *filter = impl_from_IOverlay(iface);
661 TRACE("filter %p, window %p.\n", filter, window);
663 *window = filter->baseControlWindow.baseWindow.hWnd;
664 return S_OK;
667 static HRESULT WINAPI overlay_GetClipList(IOverlay *iface, RECT *source, RECT *dest, RGNDATA **region)
669 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface, source, dest, region);
670 return E_NOTIMPL;
673 static HRESULT WINAPI overlay_GetVideoPosition(IOverlay *iface, RECT *source, RECT *dest)
675 FIXME("iface %p, source %p, dest %p, stub!\n", iface, source, dest);
676 return E_NOTIMPL;
679 static HRESULT WINAPI overlay_Advise(IOverlay *iface, IOverlayNotify *sink, DWORD flags)
681 FIXME("iface %p, sink %p, flags %#x, stub!\n", iface, sink, flags);
682 return E_NOTIMPL;
685 static HRESULT WINAPI overlay_Unadvise(IOverlay *iface)
687 FIXME("iface %p, stub!\n", iface);
688 return E_NOTIMPL;
691 static const IOverlayVtbl overlay_vtbl =
693 overlay_QueryInterface,
694 overlay_AddRef,
695 overlay_Release,
696 overlay_GetPalette,
697 overlay_SetPalette,
698 overlay_GetDefaultColorKey,
699 overlay_GetColorKey,
700 overlay_SetColorKey,
701 overlay_GetWindowHandle,
702 overlay_GetClipList,
703 overlay_GetVideoPosition,
704 overlay_Advise,
705 overlay_Unadvise,
708 HRESULT VideoRenderer_create(IUnknown *outer, void **out)
710 HRESULT hr;
711 VideoRendererImpl * pVideoRenderer;
713 *out = NULL;
715 pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl));
717 pVideoRenderer->init = FALSE;
718 ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT));
719 ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT));
720 ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT));
721 pVideoRenderer->FullScreenMode = OAFALSE;
723 pVideoRenderer->IOverlay_iface.lpVtbl = &overlay_vtbl;
725 hr = strmbase_renderer_init(&pVideoRenderer->renderer, outer,
726 &CLSID_VideoRenderer, L"In", &renderer_ops);
728 if (FAILED(hr))
729 goto fail;
731 hr = strmbase_window_init(&pVideoRenderer->baseControlWindow, &IVideoWindow_VTable,
732 &pVideoRenderer->renderer.filter, &pVideoRenderer->renderer.sink.pin,
733 &renderer_BaseWindowFuncTable);
734 if (FAILED(hr))
735 goto fail;
737 hr = strmbase_video_init(&pVideoRenderer->baseControlVideo, &pVideoRenderer->renderer.filter,
738 &pVideoRenderer->renderer.sink.pin, &renderer_BaseControlVideoFuncTable);
739 if (FAILED(hr))
740 goto fail;
742 if (FAILED(hr = BaseWindowImpl_PrepareWindow(&pVideoRenderer->baseControlWindow.baseWindow)))
743 goto fail;
745 pVideoRenderer->run_event = CreateEventW(NULL, TRUE, FALSE, NULL);
747 *out = &pVideoRenderer->renderer.filter.IUnknown_inner;
748 return S_OK;
750 fail:
751 strmbase_renderer_cleanup(&pVideoRenderer->renderer);
752 CoTaskMemFree(pVideoRenderer);
753 return hr;
756 HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv)
758 /* TODO: Attempt to use the VMR-7 renderer instead when possible */
759 return VideoRenderer_create(pUnkOuter, ppv);