1 /* 2 * Video Mixing Renderer for dx9 3 * 4 * Copyright 2004 Christian Costa 5 * Copyright 2008 Maarten Lankhorst 6 * Copyright 2012 Aric Stewart 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 23 #include "config.h" 24 25 #include "quartz_private.h" 26 27 #include "uuids.h" 28 #include "vfwmsgs.h" 29 #include "amvideo.h" 30 #include "windef.h" 31 #include "winbase.h" 32 #include "dshow.h" 33 #include "evcode.h" 34 #include "strmif.h" 35 #include "ddraw.h" 36 #include "dvdmedia.h" 37 #include "d3d9.h" 38 #include "vmr9.h" 39 #include "pin.h" 40 41 #include "wine/unicode.h" 42 #include "wine/debug.h" 43 44 WINE_DEFAULT_DEBUG_CHANNEL(quartz); 45 46 struct quartz_vmr 47 { 48 BaseRenderer renderer; 49 BaseControlWindow baseControlWindow; 50 BaseControlVideo baseControlVideo; 51 52 IUnknown IUnknown_inner; 53 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface; 54 IAMFilterMiscFlags IAMFilterMiscFlags_iface; 55 IVMRFilterConfig IVMRFilterConfig_iface; 56 IVMRFilterConfig9 IVMRFilterConfig9_iface; 57 IVMRMonitorConfig IVMRMonitorConfig_iface; 58 IVMRMonitorConfig9 IVMRMonitorConfig9_iface; 59 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface; 60 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface; 61 IVMRWindowlessControl IVMRWindowlessControl_iface; 62 IVMRWindowlessControl9 IVMRWindowlessControl9_iface; 63 64 IVMRSurfaceAllocatorEx9 *allocator; 65 IVMRImagePresenter9 *presenter; 66 BOOL allocator_is_ex; 67 68 /* 69 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed 70 * What I do is implement windowless as a special case of renderless, and then 71 * windowed also as a special case of windowless. This is probably the easiest way. 72 */ 73 VMR9Mode mode; 74 BITMAPINFOHEADER bmiheader; 75 IUnknown * outer_unk; 76 BOOL bUnkOuterValid; 77 BOOL bAggregatable; 78 79 HMODULE hD3d9; 80 81 /* Presentation related members */ 82 IDirect3DDevice9 *allocator_d3d9_dev; 83 HMONITOR allocator_mon; 84 DWORD num_surfaces; 85 DWORD cur_surface; 86 DWORD_PTR cookie; 87 88 /* for Windowless Mode */ 89 HWND hWndClippingWindow; 90 91 RECT source_rect; 92 RECT target_rect; 93 LONG VideoWidth; 94 LONG VideoHeight; 95 }; 96 97 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface) 98 { 99 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner); 100 } 101 102 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd) 103 { 104 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow); 105 } 106 107 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface) 108 { 109 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface); 110 } 111 112 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid) 113 { 114 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo); 115 } 116 117 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface) 118 { 119 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface); 120 } 121 122 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface) 123 { 124 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface); 125 } 126 127 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) 128 { 129 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface); 130 } 131 132 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface) 133 { 134 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface); 135 } 136 137 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface) 138 { 139 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface); 140 } 141 142 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface) 143 { 144 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface); 145 } 146 147 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface) 148 { 149 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface); 150 } 151 152 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface) 153 { 154 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface); 155 } 156 157 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface) 158 { 159 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface); 160 } 161 162 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface) 163 { 164 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface); 165 } 166 167 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface) 168 { 169 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface); 170 } 171 172 typedef struct 173 { 174 IVMRImagePresenter9 IVMRImagePresenter9_iface; 175 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface; 176 177 LONG refCount; 178 179 HANDLE ack; 180 DWORD tid; 181 HANDLE hWndThread; 182 183 IDirect3DDevice9 *d3d9_dev; 184 IDirect3D9 *d3d9_ptr; 185 IDirect3DSurface9 **d3d9_surfaces; 186 IDirect3DVertexBuffer9 *d3d9_vertex; 187 HMONITOR hMon; 188 DWORD num_surfaces; 189 190 BOOL reset; 191 VMR9AllocationInfo info; 192 193 struct quartz_vmr* pVMR9; 194 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify; 195 } VMR9DefaultAllocatorPresenterImpl; 196 197 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface) 198 { 199 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface); 200 } 201 202 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface) 203 { 204 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface); 205 } 206 207 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv); 208 209 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data, 210 DWORD size) 211 { 212 AM_MEDIA_TYPE *amt; 213 HRESULT hr = S_OK; 214 int width; 215 int height; 216 BITMAPINFOHEADER *bmiHeader; 217 D3DLOCKED_RECT lock; 218 219 TRACE("%p %p %d\n", This, data, size); 220 221 amt = &This->renderer.pInputPin->pin.mtCurrent; 222 223 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) 224 { 225 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; 226 } 227 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) 228 { 229 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; 230 } 231 else 232 { 233 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); 234 return VFW_E_RUNTIME_ERROR; 235 } 236 237 TRACE("biSize = %d\n", bmiHeader->biSize); 238 TRACE("biWidth = %d\n", bmiHeader->biWidth); 239 TRACE("biHeight = %d\n", bmiHeader->biHeight); 240 TRACE("biPlanes = %d\n", bmiHeader->biPlanes); 241 TRACE("biBitCount = %d\n", bmiHeader->biBitCount); 242 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4)); 243 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage); 244 245 width = bmiHeader->biWidth; 246 height = bmiHeader->biHeight; 247 248 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This->source_rect)); 249 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This->target_rect)); 250 251 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD); 252 if (FAILED(hr)) 253 { 254 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr); 255 return hr; 256 } 257 258 if (height > 0) { 259 /* Bottom up image needs inverting */ 260 lock.pBits = (char *)lock.pBits + (height * lock.Pitch); 261 while (height--) 262 { 263 lock.pBits = (char *)lock.pBits - lock.Pitch; 264 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8); 265 data = data + width * bmiHeader->biBitCount / 8; 266 } 267 } 268 else if (lock.Pitch != width * bmiHeader->biBitCount / 8) 269 { 270 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8); 271 272 while (height--) 273 { 274 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8); 275 data = data + width * bmiHeader->biBitCount / 8; 276 lock.pBits = (char *)lock.pBits + lock.Pitch; 277 } 278 } 279 else memcpy(lock.pBits, data, size); 280 281 IDirect3DSurface9_UnlockRect(info->lpSurf); 282 283 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info); 284 return hr; 285 } 286 287 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample) 288 { 289 struct quartz_vmr *This = (struct quartz_vmr*)iface; 290 LPBYTE pbSrcStream = NULL; 291 long cbSrcStream = 0; 292 REFERENCE_TIME tStart, tStop; 293 VMR9PresentationInfo info; 294 HRESULT hr; 295 296 TRACE("%p %p\n", iface, pSample); 297 298 /* It is possible that there is no device at this point */ 299 300 if (!This->allocator || !This->presenter) 301 { 302 ERR("NO PRESENTER!!\n"); 303 return S_FALSE; 304 } 305 306 hr = IMediaSample_GetTime(pSample, &tStart, &tStop); 307 if (FAILED(hr)) 308 info.dwFlags = VMR9Sample_SrcDstRectsValid; 309 else 310 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid; 311 312 if (IMediaSample_IsDiscontinuity(pSample) == S_OK) 313 info.dwFlags |= VMR9Sample_Discontinuity; 314 315 if (IMediaSample_IsPreroll(pSample) == S_OK) 316 info.dwFlags |= VMR9Sample_Preroll; 317 318 if (IMediaSample_IsSyncPoint(pSample) == S_OK) 319 info.dwFlags |= VMR9Sample_SyncPoint; 320 321 /* If we render ourselves, and this is a preroll sample, discard it */ 322 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll)) 323 { 324 return S_OK; 325 } 326 327 hr = IMediaSample_GetPointer(pSample, &pbSrcStream); 328 if (FAILED(hr)) 329 { 330 ERR("Cannot get pointer to sample data (%x)\n", hr); 331 return hr; 332 } 333 334 cbSrcStream = IMediaSample_GetActualDataLength(pSample); 335 336 info.rtStart = tStart; 337 info.rtEnd = tStop; 338 info.szAspectRatio.cx = This->bmiheader.biWidth; 339 info.szAspectRatio.cy = This->bmiheader.biHeight; 340 341 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf); 342 343 if (FAILED(hr)) 344 return hr; 345 346 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream); 347 IDirect3DSurface9_Release(info.lpSurf); 348 349 return hr; 350 } 351 352 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) 353 { 354 struct quartz_vmr *This = (struct quartz_vmr*)iface; 355 356 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat) 357 return S_FALSE; 358 359 /* Ignore subtype, test for bicompression instead */ 360 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) 361 { 362 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat; 363 364 This->bmiheader = format->bmiHeader; 365 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight); 366 This->VideoWidth = format->bmiHeader.biWidth; 367 This->VideoHeight = format->bmiHeader.biHeight; 368 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight); 369 } 370 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) 371 { 372 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat; 373 374 This->bmiheader = format->bmiHeader; 375 376 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight); 377 This->VideoWidth = format->bmiHeader.biWidth; 378 This->VideoHeight = format->bmiHeader.biHeight; 379 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight); 380 } 381 else 382 { 383 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype)); 384 return S_FALSE; 385 } 386 if (This->bmiheader.biCompression != BI_RGB) 387 return S_FALSE; 388 return S_OK; 389 } 390 391 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force) 392 { 393 VMR9AllocationInfo info; 394 DWORD buffers; 395 HRESULT hr; 396 397 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow); 398 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo) 399 return S_OK; 400 401 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow) 402 return (force ? VFW_E_RUNTIME_ERROR : S_OK); 403 404 TRACE("Initializing\n"); 405 info.dwFlags = VMR9AllocFlag_TextureSurface; 406 info.dwHeight = This->source_rect.bottom; 407 info.dwWidth = This->source_rect.right; 408 info.Pool = D3DPOOL_DEFAULT; 409 info.MinBuffers = 2; 410 FIXME("Reduce ratio to least common denominator\n"); 411 info.szAspectRatio.cx = info.dwWidth; 412 info.szAspectRatio.cy = info.dwHeight; 413 info.szNativeSize.cx = This->bmiheader.biWidth; 414 info.szNativeSize.cy = This->bmiheader.biHeight; 415 buffers = 2; 416 417 switch (This->bmiheader.biBitCount) 418 { 419 case 8: info.Format = D3DFMT_R3G3B2; break; 420 case 15: info.Format = D3DFMT_X1R5G5B5; break; 421 case 16: info.Format = D3DFMT_R5G6B5; break; 422 case 24: info.Format = D3DFMT_R8G8B8; break; 423 case 32: info.Format = D3DFMT_X8R8G8B8; break; 424 default: 425 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount); 426 hr = E_INVALIDARG; 427 } 428 429 This->cur_surface = 0; 430 if (This->num_surfaces) 431 { 432 ERR("num_surfaces or d3d9_surfaces not 0\n"); 433 return E_FAIL; 434 } 435 436 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers); 437 if (SUCCEEDED(hr)) 438 { 439 SetRect(&This->source_rect, 0, 0, This->bmiheader.biWidth, This->bmiheader.biHeight); 440 441 This->num_surfaces = buffers; 442 } 443 return hr; 444 } 445 446 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface) 447 { 448 struct quartz_vmr *This = (struct quartz_vmr*)iface; 449 450 TRACE("(%p)\n", This); 451 452 VMR9_maybe_init(This, TRUE); 453 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie); 454 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, 455 This->source_rect.left, 456 This->source_rect.top, 457 This->source_rect.right - This->source_rect.left, 458 This->source_rect.bottom - This->source_rect.top, 459 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE); 460 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW); 461 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect); 462 } 463 464 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface) 465 { 466 struct quartz_vmr *This = (struct quartz_vmr*)iface; 467 468 TRACE("(%p)\n", This); 469 470 if (This->renderer.filter.state == State_Running) 471 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie); 472 } 473 474 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime) 475 { 476 /* Preroll means the sample isn't shown, this is used for key frames and things like that */ 477 if (IMediaSample_IsPreroll(pSample) == S_OK) 478 return E_FAIL; 479 return S_FALSE; 480 } 481 482 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin) 483 { 484 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This; 485 HRESULT hr; 486 487 TRACE("(%p)\n", This); 488 489 if (pVMR9->mode || 490 SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed))) 491 hr = VMR9_maybe_init(pVMR9, FALSE); 492 493 return hr; 494 } 495 496 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This) 497 { 498 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This; 499 HRESULT hr = S_OK; 500 501 if (!pVMR9->mode) 502 return S_FALSE; 503 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter) 504 { 505 if (pVMR9->renderer.filter.state != State_Stopped) 506 { 507 ERR("Disconnecting while not stopped! UNTESTED!!\n"); 508 } 509 if (pVMR9->renderer.filter.state == State_Running) 510 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie); 511 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie); 512 pVMR9->num_surfaces = 0; 513 } 514 return hr; 515 } 516 517 static const BaseRendererFuncTable BaseFuncTable = { 518 VMR9_CheckMediaType, 519 VMR9_DoRenderSample, 520 /**/ 521 NULL, 522 NULL, 523 NULL, 524 VMR9_OnStartStreaming, 525 VMR9_OnStopStreaming, 526 NULL, 527 NULL, 528 NULL, 529 VMR9_ShouldDrawSampleNow, 530 NULL, 531 /**/ 532 VMR9_CompleteConnect, 533 VMR9_BreakConnect, 534 NULL, 535 NULL, 536 NULL, 537 }; 538 539 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx) 540 { 541 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 }; 542 543 *pClassStyles = 0; 544 *pWindowStyles = WS_SIZEBOX; 545 *pWindowStylesEx = 0; 546 547 return classnameW; 548 } 549 550 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This) 551 { 552 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This); 553 static RECT defRect; 554 555 SetRect(&defRect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight); 556 557 return defRect; 558 } 559 560 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height) 561 { 562 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This); 563 564 TRACE("WM_SIZE %d %d\n", Width, Height); 565 GetClientRect(This->hWnd, &pVMR9->target_rect); 566 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", 567 pVMR9->target_rect.left, 568 pVMR9->target_rect.top, 569 pVMR9->target_rect.right - pVMR9->target_rect.left, 570 pVMR9->target_rect.bottom - pVMR9->target_rect.top); 571 return BaseWindowImpl_OnSize(This, Width, Height); 572 } 573 574 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = { 575 VMR9_GetClassWindowStyles, 576 VMR9_GetDefaultRect, 577 NULL, 578 BaseControlWindowImpl_PossiblyEatMessage, 579 VMR9_OnSize, 580 }; 581 582 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect) 583 { 584 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 585 CopyRect(pSourceRect,&pVMR9->source_rect); 586 return S_OK; 587 } 588 589 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage) 590 { 591 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 592 BITMAPINFOHEADER *bmiHeader; 593 LONG needed_size; 594 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent; 595 char *ptr; 596 597 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage); 598 599 EnterCriticalSection(&pVMR9->renderer.filter.csFilter); 600 601 if (!pVMR9->renderer.pMediaSample) 602 { 603 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); 604 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); 605 } 606 607 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) 608 { 609 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; 610 } 611 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) 612 { 613 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; 614 } 615 else 616 { 617 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); 618 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); 619 return VFW_E_RUNTIME_ERROR; 620 } 621 622 needed_size = bmiHeader->biSize; 623 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample); 624 625 if (!pDIBImage) 626 { 627 *pBufferSize = needed_size; 628 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); 629 return S_OK; 630 } 631 632 if (needed_size < *pBufferSize) 633 { 634 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize); 635 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); 636 return E_FAIL; 637 } 638 *pBufferSize = needed_size; 639 640 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); 641 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr); 642 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample)); 643 644 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); 645 return S_OK; 646 } 647 648 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect) 649 { 650 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 651 CopyRect(pTargetRect,&pVMR9->target_rect); 652 return S_OK; 653 } 654 655 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This) 656 { 657 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 658 AM_MEDIA_TYPE *pmt; 659 660 TRACE("(%p/%p)\n", pVMR9, This); 661 662 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent; 663 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { 664 return (VIDEOINFOHEADER*)pmt->pbFormat; 665 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { 666 static VIDEOINFOHEADER vih; 667 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat; 668 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER)); 669 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER)); 670 return &vih; 671 } else { 672 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); 673 return NULL; 674 } 675 } 676 677 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This) 678 { 679 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 680 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This); 681 682 return S_OK; 683 } 684 685 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This) 686 { 687 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 688 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This); 689 690 return S_OK; 691 } 692 693 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This) 694 { 695 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 696 697 SetRect(&pVMR9->source_rect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight); 698 699 return S_OK; 700 } 701 702 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This) 703 { 704 RECT rect; 705 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 706 707 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect)) 708 return E_FAIL; 709 710 SetRect(&pVMR9->target_rect, 0, 0, rect.right, rect.bottom); 711 712 return S_OK; 713 } 714 715 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect) 716 { 717 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 718 CopyRect(&pVMR9->source_rect,pSourceRect); 719 return S_OK; 720 } 721 722 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect) 723 { 724 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This); 725 CopyRect(&pVMR9->target_rect,pTargetRect); 726 return S_OK; 727 } 728 729 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { 730 VMR9_GetSourceRect, 731 VMR9_GetStaticImage, 732 VMR9_GetTargetRect, 733 VMR9_GetVideoFormat, 734 VMR9_IsDefaultSourceRect, 735 VMR9_IsDefaultTargetRect, 736 VMR9_SetDefaultSourceRect, 737 VMR9_SetDefaultTargetRect, 738 VMR9_SetSourceRect, 739 VMR9_SetTargetRect 740 }; 741 742 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) 743 { 744 struct quartz_vmr *This = impl_from_inner_IUnknown(iface); 745 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); 746 747 if (This->bAggregatable) 748 This->bUnkOuterValid = TRUE; 749 750 *ppv = NULL; 751 752 if (IsEqualIID(riid, &IID_IUnknown)) 753 *ppv = &This->IUnknown_inner; 754 else if (IsEqualIID(riid, &IID_IVideoWindow)) 755 *ppv = &This->baseControlWindow.IVideoWindow_iface; 756 else if (IsEqualIID(riid, &IID_IBasicVideo)) 757 *ppv = &This->baseControlVideo.IBasicVideo_iface; 758 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection)) 759 *ppv = &This->IAMCertifiedOutputProtection_iface; 760 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) 761 *ppv = &This->IAMFilterMiscFlags_iface; 762 else if (IsEqualIID(riid, &IID_IVMRFilterConfig)) 763 *ppv = &This->IVMRFilterConfig_iface; 764 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9)) 765 *ppv = &This->IVMRFilterConfig9_iface; 766 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig)) 767 *ppv = &This->IVMRMonitorConfig_iface; 768 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9)) 769 *ppv = &This->IVMRMonitorConfig9_iface; 770 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless) 771 *ppv = &This->IVMRSurfaceAllocatorNotify_iface; 772 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless) 773 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface; 774 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless) 775 *ppv = &This->IVMRWindowlessControl_iface; 776 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless) 777 *ppv = &This->IVMRWindowlessControl9_iface; 778 else 779 { 780 HRESULT hr; 781 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 782 if (SUCCEEDED(hr)) 783 return hr; 784 } 785 786 if (*ppv) 787 { 788 IUnknown_AddRef((IUnknown *)(*ppv)); 789 return S_OK; 790 } 791 792 else if (IsEqualIID(riid, &IID_IBasicVideo2)) 793 FIXME("No interface for IID_IBasicVideo2\n"); 794 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9)) 795 ; 796 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9)) 797 ; 798 else if (IsEqualIID(riid, &IID_IMediaPosition)) 799 FIXME("No interface for IID_IMediaPosition\n"); 800 else if (IsEqualIID(riid, &IID_IQualProp)) 801 FIXME("No interface for IID_IQualProp\n"); 802 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9)) 803 FIXME("No interface for IID_IVMRAspectRatioControl9\n"); 804 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9)) 805 FIXME("No interface for IID_IVMRDeinterlaceControl9\n"); 806 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9)) 807 FIXME("No interface for IID_IVMRMixerBitmap9\n"); 808 else if (IsEqualIID(riid, &IID_IVMRMixerControl9)) 809 FIXME("No interface for IID_IVMRMixerControl9\n"); 810 else 811 FIXME("No interface for %s\n", debugstr_guid(riid)); 812 813 return E_NOINTERFACE; 814 } 815 816 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface) 817 { 818 struct quartz_vmr *This = impl_from_inner_IUnknown(iface); 819 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); 820 821 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); 822 823 return refCount; 824 } 825 826 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface) 827 { 828 struct quartz_vmr *This = impl_from_inner_IUnknown(iface); 829 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface); 830 831 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); 832 833 if (!refCount) 834 { 835 TRACE("Destroying\n"); 836 BaseControlWindow_Destroy(&This->baseControlWindow); 837 FreeLibrary(This->hD3d9); 838 839 if (This->allocator) 840 IVMRSurfaceAllocatorEx9_Release(This->allocator); 841 if (This->presenter) 842 IVMRImagePresenter9_Release(This->presenter); 843 844 This->num_surfaces = 0; 845 if (This->allocator_d3d9_dev) 846 { 847 IDirect3DDevice9_Release(This->allocator_d3d9_dev); 848 This->allocator_d3d9_dev = NULL; 849 } 850 851 CoTaskMemFree(This); 852 } 853 return refCount; 854 } 855 856 static const IUnknownVtbl IInner_VTable = 857 { 858 VMR9Inner_QueryInterface, 859 VMR9Inner_AddRef, 860 VMR9Inner_Release 861 }; 862 863 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) 864 { 865 struct quartz_vmr *This = (struct quartz_vmr*)iface; 866 867 if (This->bAggregatable) 868 This->bUnkOuterValid = TRUE; 869 870 if (This->outer_unk) 871 { 872 if (This->bAggregatable) 873 return IUnknown_QueryInterface(This->outer_unk, riid, ppv); 874 875 if (IsEqualIID(riid, &IID_IUnknown)) 876 { 877 HRESULT hr; 878 879 IUnknown_AddRef(&This->IUnknown_inner); 880 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); 881 IUnknown_Release(&This->IUnknown_inner); 882 This->bAggregatable = TRUE; 883 return hr; 884 } 885 886 *ppv = NULL; 887 return E_NOINTERFACE; 888 } 889 890 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); 891 } 892 893 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface) 894 { 895 struct quartz_vmr *This = (struct quartz_vmr*)iface; 896 LONG ret; 897 898 if (This->outer_unk && This->bUnkOuterValid) 899 ret = IUnknown_AddRef(This->outer_unk); 900 else 901 ret = IUnknown_AddRef(&This->IUnknown_inner); 902 903 TRACE("(%p)->AddRef from %d\n", iface, ret - 1); 904 905 return ret; 906 } 907 908 static ULONG WINAPI VMR9_Release(IBaseFilter * iface) 909 { 910 struct quartz_vmr *This = (struct quartz_vmr*)iface; 911 LONG ret; 912 913 if (This->outer_unk && This->bUnkOuterValid) 914 ret = IUnknown_Release(This->outer_unk); 915 else 916 ret = IUnknown_Release(&This->IUnknown_inner); 917 918 TRACE("(%p)->Release from %d\n", iface, ret + 1); 919 920 if (ret) 921 return ret; 922 return 0; 923 } 924 925 static const IBaseFilterVtbl VMR_Vtbl = 926 { 927 VMR9_QueryInterface, 928 VMR9_AddRef, 929 VMR9_Release, 930 BaseFilterImpl_GetClassID, 931 BaseRendererImpl_Stop, 932 BaseRendererImpl_Pause, 933 BaseRendererImpl_Run, 934 BaseRendererImpl_GetState, 935 BaseRendererImpl_SetSyncSource, 936 BaseFilterImpl_GetSyncSource, 937 BaseFilterImpl_EnumPins, 938 BaseRendererImpl_FindPin, 939 BaseFilterImpl_QueryFilterInfo, 940 BaseFilterImpl_JoinFilterGraph, 941 BaseFilterImpl_QueryVendorInfo 942 }; 943 944 /*** IUnknown methods ***/ 945 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj) 946 { 947 struct quartz_vmr *This = impl_from_IVideoWindow(iface); 948 949 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj); 950 951 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); 952 } 953 954 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) 955 { 956 struct quartz_vmr *This = impl_from_IVideoWindow(iface); 957 958 TRACE("(%p/%p)->()\n", This, iface); 959 960 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 961 } 962 963 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) 964 { 965 struct quartz_vmr *This = impl_from_IVideoWindow(iface); 966 967 TRACE("(%p/%p)->()\n", This, iface); 968 969 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 970 } 971 972 static const IVideoWindowVtbl IVideoWindow_VTable = 973 { 974 Videowindow_QueryInterface, 975 Videowindow_AddRef, 976 Videowindow_Release, 977 BaseControlWindowImpl_GetTypeInfoCount, 978 BaseControlWindowImpl_GetTypeInfo, 979 BaseControlWindowImpl_GetIDsOfNames, 980 BaseControlWindowImpl_Invoke, 981 BaseControlWindowImpl_put_Caption, 982 BaseControlWindowImpl_get_Caption, 983 BaseControlWindowImpl_put_WindowStyle, 984 BaseControlWindowImpl_get_WindowStyle, 985 BaseControlWindowImpl_put_WindowStyleEx, 986 BaseControlWindowImpl_get_WindowStyleEx, 987 BaseControlWindowImpl_put_AutoShow, 988 BaseControlWindowImpl_get_AutoShow, 989 BaseControlWindowImpl_put_WindowState, 990 BaseControlWindowImpl_get_WindowState, 991 BaseControlWindowImpl_put_BackgroundPalette, 992 BaseControlWindowImpl_get_BackgroundPalette, 993 BaseControlWindowImpl_put_Visible, 994 BaseControlWindowImpl_get_Visible, 995 BaseControlWindowImpl_put_Left, 996 BaseControlWindowImpl_get_Left, 997 BaseControlWindowImpl_put_Width, 998 BaseControlWindowImpl_get_Width, 999 BaseControlWindowImpl_put_Top, 1000 BaseControlWindowImpl_get_Top, 1001 BaseControlWindowImpl_put_Height, 1002 BaseControlWindowImpl_get_Height, 1003 BaseControlWindowImpl_put_Owner, 1004 BaseControlWindowImpl_get_Owner, 1005 BaseControlWindowImpl_put_MessageDrain, 1006 BaseControlWindowImpl_get_MessageDrain, 1007 BaseControlWindowImpl_get_BorderColor, 1008 BaseControlWindowImpl_put_BorderColor, 1009 BaseControlWindowImpl_get_FullScreenMode, 1010 BaseControlWindowImpl_put_FullScreenMode, 1011 BaseControlWindowImpl_SetWindowForeground, 1012 BaseControlWindowImpl_NotifyOwnerMessage, 1013 BaseControlWindowImpl_SetWindowPosition, 1014 BaseControlWindowImpl_GetWindowPosition, 1015 BaseControlWindowImpl_GetMinIdealImageSize, 1016 BaseControlWindowImpl_GetMaxIdealImageSize, 1017 BaseControlWindowImpl_GetRestorePosition, 1018 BaseControlWindowImpl_HideCursor, 1019 BaseControlWindowImpl_IsCursorHidden 1020 }; 1021 1022 /*** IUnknown methods ***/ 1023 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj) 1024 { 1025 struct quartz_vmr *This = impl_from_IBasicVideo(iface); 1026 1027 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj); 1028 1029 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); 1030 } 1031 1032 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) 1033 { 1034 struct quartz_vmr *This = impl_from_IBasicVideo(iface); 1035 1036 TRACE("(%p/%p)->()\n", This, iface); 1037 1038 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1039 } 1040 1041 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) 1042 { 1043 struct quartz_vmr *This = impl_from_IBasicVideo(iface); 1044 1045 TRACE("(%p/%p)->()\n", This, iface); 1046 1047 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1048 } 1049 1050 static const IBasicVideoVtbl IBasicVideo_VTable = 1051 { 1052 Basicvideo_QueryInterface, 1053 Basicvideo_AddRef, 1054 Basicvideo_Release, 1055 BaseControlVideoImpl_GetTypeInfoCount, 1056 BaseControlVideoImpl_GetTypeInfo, 1057 BaseControlVideoImpl_GetIDsOfNames, 1058 BaseControlVideoImpl_Invoke, 1059 BaseControlVideoImpl_get_AvgTimePerFrame, 1060 BaseControlVideoImpl_get_BitRate, 1061 BaseControlVideoImpl_get_BitErrorRate, 1062 BaseControlVideoImpl_get_VideoWidth, 1063 BaseControlVideoImpl_get_VideoHeight, 1064 BaseControlVideoImpl_put_SourceLeft, 1065 BaseControlVideoImpl_get_SourceLeft, 1066 BaseControlVideoImpl_put_SourceWidth, 1067 BaseControlVideoImpl_get_SourceWidth, 1068 BaseControlVideoImpl_put_SourceTop, 1069 BaseControlVideoImpl_get_SourceTop, 1070 BaseControlVideoImpl_put_SourceHeight, 1071 BaseControlVideoImpl_get_SourceHeight, 1072 BaseControlVideoImpl_put_DestinationLeft, 1073 BaseControlVideoImpl_get_DestinationLeft, 1074 BaseControlVideoImpl_put_DestinationWidth, 1075 BaseControlVideoImpl_get_DestinationWidth, 1076 BaseControlVideoImpl_put_DestinationTop, 1077 BaseControlVideoImpl_get_DestinationTop, 1078 BaseControlVideoImpl_put_DestinationHeight, 1079 BaseControlVideoImpl_get_DestinationHeight, 1080 BaseControlVideoImpl_SetSourcePosition, 1081 BaseControlVideoImpl_GetSourcePosition, 1082 BaseControlVideoImpl_SetDefaultSourcePosition, 1083 BaseControlVideoImpl_SetDestinationPosition, 1084 BaseControlVideoImpl_GetDestinationPosition, 1085 BaseControlVideoImpl_SetDefaultDestinationPosition, 1086 BaseControlVideoImpl_GetVideoSize, 1087 BaseControlVideoImpl_GetVideoPaletteEntries, 1088 BaseControlVideoImpl_GetCurrentImage, 1089 BaseControlVideoImpl_IsUsingDefaultSource, 1090 BaseControlVideoImpl_IsUsingDefaultDestination 1091 }; 1092 1093 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface, 1094 REFIID riid, void **ppv) 1095 { 1096 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1097 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1098 } 1099 1100 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface) 1101 { 1102 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1103 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1104 } 1105 1106 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface) 1107 { 1108 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1109 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1110 } 1111 1112 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface, 1113 GUID* pRandom, BYTE** VarLenCertGH, 1114 DWORD* pdwLengthCertGH) 1115 { 1116 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1117 1118 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH); 1119 return VFW_E_NO_COPP_HW; 1120 } 1121 1122 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface, 1123 AMCOPPSignature* pSig) 1124 { 1125 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1126 1127 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig); 1128 return VFW_E_NO_COPP_HW; 1129 } 1130 1131 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface, 1132 const AMCOPPCommand* cmd) 1133 { 1134 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1135 1136 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd); 1137 return VFW_E_NO_COPP_HW; 1138 } 1139 1140 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface, 1141 const AMCOPPStatusInput* pStatusInput, 1142 AMCOPPStatusOutput* pStatusOutput) 1143 { 1144 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface); 1145 1146 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput); 1147 return VFW_E_NO_COPP_HW; 1148 } 1149 1150 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl = 1151 { 1152 AMCertifiedOutputProtection_QueryInterface, 1153 AMCertifiedOutputProtection_AddRef, 1154 AMCertifiedOutputProtection_Release, 1155 AMCertifiedOutputProtection_KeyExchange, 1156 AMCertifiedOutputProtection_SessionSequenceStart, 1157 AMCertifiedOutputProtection_ProtectionCommand, 1158 AMCertifiedOutputProtection_ProtectionStatus 1159 }; 1160 1161 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) { 1162 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface); 1163 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1164 } 1165 1166 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) { 1167 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface); 1168 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1169 } 1170 1171 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) { 1172 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface); 1173 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1174 } 1175 1176 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) { 1177 return AM_FILTER_MISC_FLAGS_IS_RENDERER; 1178 } 1179 1180 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { 1181 AMFilterMiscFlags_QueryInterface, 1182 AMFilterMiscFlags_AddRef, 1183 AMFilterMiscFlags_Release, 1184 AMFilterMiscFlags_GetMiscFlags 1185 }; 1186 1187 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid, 1188 void** ppv) 1189 { 1190 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1191 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1192 } 1193 1194 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface) 1195 { 1196 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1197 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1198 } 1199 1200 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface) 1201 { 1202 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1203 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1204 } 1205 1206 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface, 1207 IVMRImageCompositor *compositor) 1208 { 1209 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1210 1211 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor); 1212 return E_NOTIMPL; 1213 } 1214 1215 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max) 1216 { 1217 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1218 1219 FIXME("(%p/%p)->(%u) stub\n", iface, This, max); 1220 return E_NOTIMPL; 1221 } 1222 1223 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max) 1224 { 1225 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1226 1227 FIXME("(%p/%p)->(%p) stub\n", iface, This, max); 1228 return E_NOTIMPL; 1229 } 1230 1231 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags) 1232 { 1233 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1234 1235 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags); 1236 return E_NOTIMPL; 1237 } 1238 1239 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags) 1240 { 1241 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1242 1243 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags); 1244 return E_NOTIMPL; 1245 } 1246 1247 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode) 1248 { 1249 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1250 1251 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode); 1252 return E_NOTIMPL; 1253 } 1254 1255 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode) 1256 { 1257 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); 1258 1259 TRACE("(%p/%p)->(%p)\n", iface, This, mode); 1260 if (!mode) return E_POINTER; 1261 1262 if (This->mode) 1263 *mode = This->mode; 1264 else 1265 *mode = VMRMode_Windowed; 1266 1267 return S_OK; 1268 } 1269 1270 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl = 1271 { 1272 VMR7FilterConfig_QueryInterface, 1273 VMR7FilterConfig_AddRef, 1274 VMR7FilterConfig_Release, 1275 VMR7FilterConfig_SetImageCompositor, 1276 VMR7FilterConfig_SetNumberOfStreams, 1277 VMR7FilterConfig_GetNumberOfStreams, 1278 VMR7FilterConfig_SetRenderingPrefs, 1279 VMR7FilterConfig_GetRenderingPrefs, 1280 VMR7FilterConfig_SetRenderingMode, 1281 VMR7FilterConfig_GetRenderingMode 1282 }; 1283 1284 struct get_available_monitors_args 1285 { 1286 VMRMONITORINFO *info7; 1287 VMR9MonitorInfo *info9; 1288 DWORD arraysize; 1289 DWORD numdev; 1290 }; 1291 1292 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam) 1293 { 1294 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam; 1295 MONITORINFOEXW mi; 1296 1297 if (args->info7 || args->info9) 1298 { 1299 1300 if (!args->arraysize) 1301 return FALSE; 1302 1303 mi.cbSize = sizeof(mi); 1304 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi)) 1305 return TRUE; 1306 1307 /* fill VMRMONITORINFO struct */ 1308 if (args->info7) 1309 { 1310 VMRMONITORINFO *info = args->info7++; 1311 memset(info, 0, sizeof(*info)); 1312 1313 if (args->numdev > 0) 1314 { 1315 info->guid.pGUID = &info->guid.GUID; 1316 info->guid.GUID.Data4[7] = args->numdev; 1317 } 1318 else 1319 info->guid.pGUID = NULL; 1320 1321 info->rcMonitor = mi.rcMonitor; 1322 info->hMon = hmon; 1323 info->dwFlags = mi.dwFlags; 1324 1325 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR)); 1326 1327 /* FIXME: how to get these values? */ 1328 info->szDescription[0] = 0; 1329 } 1330 1331 /* fill VMR9MonitorInfo struct */ 1332 if (args->info9) 1333 { 1334 VMR9MonitorInfo *info = args->info9++; 1335 memset(info, 0, sizeof(*info)); 1336 1337 info->uDevID = 0; /* FIXME */ 1338 info->rcMonitor = mi.rcMonitor; 1339 info->hMon = hmon; 1340 info->dwFlags = mi.dwFlags; 1341 1342 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR)); 1343 1344 /* FIXME: how to get these values? */ 1345 info->szDescription[0] = 0; 1346 info->dwVendorId = 0; 1347 info->dwDeviceId = 0; 1348 info->dwSubSysId = 0; 1349 info->dwRevision = 0; 1350 } 1351 1352 args->arraysize--; 1353 } 1354 1355 args->numdev++; 1356 return TRUE; 1357 } 1358 1359 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid, 1360 LPVOID * ppv) 1361 { 1362 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1363 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1364 } 1365 1366 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface) 1367 { 1368 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1369 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1370 } 1371 1372 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface) 1373 { 1374 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1375 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1376 } 1377 1378 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID) 1379 { 1380 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1381 1382 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID); 1383 1384 if (!pGUID) 1385 return E_POINTER; 1386 1387 return S_OK; 1388 } 1389 1390 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID) 1391 { 1392 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1393 1394 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID); 1395 1396 if (!pGUID) 1397 return E_POINTER; 1398 1399 pGUID->pGUID = NULL; /* default DirectDraw device */ 1400 return S_OK; 1401 } 1402 1403 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface, 1404 const VMRGUID *pGUID) 1405 { 1406 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1407 1408 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID); 1409 1410 if (!pGUID) 1411 return E_POINTER; 1412 1413 return S_OK; 1414 } 1415 1416 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID) 1417 { 1418 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1419 1420 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID); 1421 1422 if (!pGUID) 1423 return E_POINTER; 1424 1425 pGUID->pGUID = NULL; /* default DirectDraw device */ 1426 return S_OK; 1427 } 1428 1429 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface, 1430 VMRMONITORINFO *info, DWORD arraysize, 1431 DWORD *numdev) 1432 { 1433 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface); 1434 struct get_available_monitors_args args; 1435 1436 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev); 1437 1438 if (!numdev) 1439 return E_POINTER; 1440 1441 if (info && arraysize == 0) 1442 return E_INVALIDARG; 1443 1444 args.info7 = info; 1445 args.info9 = NULL; 1446 args.arraysize = arraysize; 1447 args.numdev = 0; 1448 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args); 1449 1450 *numdev = args.numdev; 1451 return S_OK; 1452 } 1453 1454 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl = 1455 { 1456 VMR7MonitorConfig_QueryInterface, 1457 VMR7MonitorConfig_AddRef, 1458 VMR7MonitorConfig_Release, 1459 VMR7MonitorConfig_SetMonitor, 1460 VMR7MonitorConfig_GetMonitor, 1461 VMR7MonitorConfig_SetDefaultMonitor, 1462 VMR7MonitorConfig_GetDefaultMonitor, 1463 VMR7MonitorConfig_GetAvailableMonitors 1464 }; 1465 1466 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid, 1467 LPVOID * ppv) 1468 { 1469 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1470 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1471 } 1472 1473 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface) 1474 { 1475 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1476 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1477 } 1478 1479 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface) 1480 { 1481 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1482 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1483 } 1484 1485 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev) 1486 { 1487 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1488 1489 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev); 1490 1491 return S_OK; 1492 } 1493 1494 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev) 1495 { 1496 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1497 1498 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev); 1499 1500 if (!uDev) 1501 return E_POINTER; 1502 1503 *uDev = 0; 1504 return S_OK; 1505 } 1506 1507 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev) 1508 { 1509 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1510 1511 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev); 1512 1513 return S_OK; 1514 } 1515 1516 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev) 1517 { 1518 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1519 1520 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev); 1521 1522 if (!uDev) 1523 return E_POINTER; 1524 1525 *uDev = 0; 1526 return S_OK; 1527 } 1528 1529 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface, 1530 VMR9MonitorInfo *info, DWORD arraysize, 1531 DWORD *numdev) 1532 { 1533 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface); 1534 struct get_available_monitors_args args; 1535 1536 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev); 1537 1538 if (!numdev) 1539 return E_POINTER; 1540 1541 if (info && arraysize == 0) 1542 return E_INVALIDARG; 1543 1544 args.info7 = NULL; 1545 args.info9 = info; 1546 args.arraysize = arraysize; 1547 args.numdev = 0; 1548 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args); 1549 1550 *numdev = args.numdev; 1551 return S_OK; 1552 } 1553 1554 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl = 1555 { 1556 VMR9MonitorConfig_QueryInterface, 1557 VMR9MonitorConfig_AddRef, 1558 VMR9MonitorConfig_Release, 1559 VMR9MonitorConfig_SetMonitor, 1560 VMR9MonitorConfig_GetMonitor, 1561 VMR9MonitorConfig_SetDefaultMonitor, 1562 VMR9MonitorConfig_GetDefaultMonitor, 1563 VMR9MonitorConfig_GetAvailableMonitors 1564 }; 1565 1566 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv) 1567 { 1568 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1569 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1570 } 1571 1572 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface) 1573 { 1574 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1575 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1576 } 1577 1578 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface) 1579 { 1580 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1581 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1582 } 1583 1584 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor) 1585 { 1586 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1587 1588 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor); 1589 return E_NOTIMPL; 1590 } 1591 1592 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max) 1593 { 1594 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1595 1596 FIXME("(%p/%p)->(%u) stub\n", iface, This, max); 1597 return E_NOTIMPL; 1598 } 1599 1600 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max) 1601 { 1602 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1603 1604 FIXME("(%p/%p)->(%p) stub\n", iface, This, max); 1605 return E_NOTIMPL; 1606 } 1607 1608 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags) 1609 { 1610 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1611 1612 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags); 1613 return E_NOTIMPL; 1614 } 1615 1616 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags) 1617 { 1618 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1619 1620 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags); 1621 return E_NOTIMPL; 1622 } 1623 1624 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode) 1625 { 1626 HRESULT hr = S_OK; 1627 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1628 1629 TRACE("(%p/%p)->(%u)\n", iface, This, mode); 1630 1631 EnterCriticalSection(&This->renderer.filter.csFilter); 1632 if (This->mode) 1633 { 1634 LeaveCriticalSection(&This->renderer.filter.csFilter); 1635 return VFW_E_WRONG_STATE; 1636 } 1637 1638 if (This->allocator) 1639 IVMRSurfaceAllocatorEx9_Release(This->allocator); 1640 if (This->presenter) 1641 IVMRImagePresenter9_Release(This->presenter); 1642 1643 This->allocator = NULL; 1644 This->presenter = NULL; 1645 1646 switch (mode) 1647 { 1648 case VMR9Mode_Windowed: 1649 case VMR9Mode_Windowless: 1650 This->allocator_is_ex = 0; 1651 This->cookie = ~0; 1652 1653 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter); 1654 if (SUCCEEDED(hr)) 1655 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator); 1656 if (FAILED(hr)) 1657 { 1658 ERR("Unable to find Presenter interface\n"); 1659 IVMRImagePresenter9_Release(This->presenter); 1660 This->allocator = NULL; 1661 This->presenter = NULL; 1662 } 1663 else 1664 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface); 1665 break; 1666 case VMR9Mode_Renderless: 1667 break; 1668 default: 1669 LeaveCriticalSection(&This->renderer.filter.csFilter); 1670 return E_INVALIDARG; 1671 } 1672 1673 This->mode = mode; 1674 LeaveCriticalSection(&This->renderer.filter.csFilter); 1675 return hr; 1676 } 1677 1678 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode) 1679 { 1680 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); 1681 1682 TRACE("(%p/%p)->(%p)\n", iface, This, mode); 1683 if (!mode) 1684 return E_POINTER; 1685 1686 if (This->mode) 1687 *mode = This->mode; 1688 else 1689 *mode = VMR9Mode_Windowed; 1690 1691 return S_OK; 1692 } 1693 1694 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl = 1695 { 1696 VMR9FilterConfig_QueryInterface, 1697 VMR9FilterConfig_AddRef, 1698 VMR9FilterConfig_Release, 1699 VMR9FilterConfig_SetImageCompositor, 1700 VMR9FilterConfig_SetNumberOfStreams, 1701 VMR9FilterConfig_GetNumberOfStreams, 1702 VMR9FilterConfig_SetRenderingPrefs, 1703 VMR9FilterConfig_GetRenderingPrefs, 1704 VMR9FilterConfig_SetRenderingMode, 1705 VMR9FilterConfig_GetRenderingMode 1706 }; 1707 1708 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid, 1709 LPVOID * ppv) 1710 { 1711 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1712 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1713 } 1714 1715 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface) 1716 { 1717 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1718 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1719 } 1720 1721 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface) 1722 { 1723 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1724 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1725 } 1726 1727 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface, 1728 LONG *width, LONG *height, 1729 LONG *arwidth, LONG *arheight) 1730 { 1731 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1732 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight); 1733 1734 if (!width || !height || !arwidth || !arheight) 1735 { 1736 ERR("Got no pointer\n"); 1737 return E_POINTER; 1738 } 1739 1740 *width = This->bmiheader.biWidth; 1741 *height = This->bmiheader.biHeight; 1742 *arwidth = This->bmiheader.biWidth; 1743 *arheight = This->bmiheader.biHeight; 1744 1745 return S_OK; 1746 } 1747 1748 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface, 1749 LONG *width, LONG *height) 1750 { 1751 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1752 1753 FIXME("(%p/%p)->(...) stub\n", iface, This); 1754 return E_NOTIMPL; 1755 } 1756 1757 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface, 1758 LONG *width, LONG *height) 1759 { 1760 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1761 1762 FIXME("(%p/%p)->(...) stub\n", iface, This); 1763 return E_NOTIMPL; 1764 } 1765 1766 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface, 1767 const RECT *source, const RECT *dest) 1768 { 1769 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1770 1771 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest); 1772 1773 EnterCriticalSection(&This->renderer.filter.csFilter); 1774 1775 if (source) 1776 This->source_rect = *source; 1777 if (dest) 1778 { 1779 This->target_rect = *dest; 1780 if (This->baseControlWindow.baseWindow.hWnd) 1781 { 1782 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest)); 1783 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, 1784 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top, 1785 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW); 1786 } 1787 } 1788 1789 LeaveCriticalSection(&This->renderer.filter.csFilter); 1790 1791 return S_OK; 1792 } 1793 1794 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface, 1795 RECT *source, RECT *dest) 1796 { 1797 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1798 1799 if (source) 1800 *source = This->source_rect; 1801 1802 if (dest) 1803 *dest = This->target_rect; 1804 1805 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest); 1806 return S_OK; 1807 } 1808 1809 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface, 1810 DWORD *mode) 1811 { 1812 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1813 1814 FIXME("(%p/%p)->(...) stub\n", iface, This); 1815 return E_NOTIMPL; 1816 } 1817 1818 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface, 1819 DWORD mode) 1820 { 1821 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1822 1823 FIXME("(%p/%p)->(...) stub\n", iface, This); 1824 return E_NOTIMPL; 1825 } 1826 1827 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface, 1828 HWND hwnd) 1829 { 1830 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1831 1832 FIXME("(%p/%p)->(...) stub\n", iface, This); 1833 return E_NOTIMPL; 1834 } 1835 1836 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface, 1837 HWND hwnd, HDC hdc) 1838 { 1839 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1840 1841 FIXME("(%p/%p)->(...) stub\n", iface, This); 1842 return E_NOTIMPL; 1843 } 1844 1845 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface) 1846 { 1847 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1848 1849 FIXME("(%p/%p)->(...) stub\n", iface, This); 1850 return E_NOTIMPL; 1851 } 1852 1853 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface, 1854 BYTE **dib) 1855 { 1856 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1857 1858 FIXME("(%p/%p)->(...) stub\n", iface, This); 1859 return E_NOTIMPL; 1860 } 1861 1862 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface, 1863 COLORREF color) 1864 { 1865 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1866 1867 FIXME("(%p/%p)->(...) stub\n", iface, This); 1868 return E_NOTIMPL; 1869 } 1870 1871 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface, 1872 COLORREF *color) 1873 { 1874 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1875 1876 FIXME("(%p/%p)->(...) stub\n", iface, This); 1877 return E_NOTIMPL; 1878 } 1879 1880 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color) 1881 { 1882 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1883 1884 FIXME("(%p/%p)->(...) stub\n", iface, This); 1885 return E_NOTIMPL; 1886 } 1887 1888 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color) 1889 { 1890 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface); 1891 1892 FIXME("(%p/%p)->(...) stub\n", iface, This); 1893 return E_NOTIMPL; 1894 } 1895 1896 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl = 1897 { 1898 VMR7WindowlessControl_QueryInterface, 1899 VMR7WindowlessControl_AddRef, 1900 VMR7WindowlessControl_Release, 1901 VMR7WindowlessControl_GetNativeVideoSize, 1902 VMR7WindowlessControl_GetMinIdealVideoSize, 1903 VMR7WindowlessControl_GetMaxIdealVideoSize, 1904 VMR7WindowlessControl_SetVideoPosition, 1905 VMR7WindowlessControl_GetVideoPosition, 1906 VMR7WindowlessControl_GetAspectRatioMode, 1907 VMR7WindowlessControl_SetAspectRatioMode, 1908 VMR7WindowlessControl_SetVideoClippingWindow, 1909 VMR7WindowlessControl_RepaintVideo, 1910 VMR7WindowlessControl_DisplayModeChanged, 1911 VMR7WindowlessControl_GetCurrentImage, 1912 VMR7WindowlessControl_SetBorderColor, 1913 VMR7WindowlessControl_GetBorderColor, 1914 VMR7WindowlessControl_SetColorKey, 1915 VMR7WindowlessControl_GetColorKey 1916 }; 1917 1918 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv) 1919 { 1920 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1921 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 1922 } 1923 1924 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface) 1925 { 1926 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1927 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 1928 } 1929 1930 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface) 1931 { 1932 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1933 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 1934 } 1935 1936 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight) 1937 { 1938 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1939 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight); 1940 1941 if (!width || !height || !arwidth || !arheight) 1942 { 1943 ERR("Got no pointer\n"); 1944 return E_POINTER; 1945 } 1946 1947 *width = This->bmiheader.biWidth; 1948 *height = This->bmiheader.biHeight; 1949 *arwidth = This->bmiheader.biWidth; 1950 *arheight = This->bmiheader.biHeight; 1951 1952 return S_OK; 1953 } 1954 1955 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height) 1956 { 1957 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1958 1959 FIXME("(%p/%p)->(...) stub\n", iface, This); 1960 return E_NOTIMPL; 1961 } 1962 1963 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height) 1964 { 1965 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1966 1967 FIXME("(%p/%p)->(...) stub\n", iface, This); 1968 return E_NOTIMPL; 1969 } 1970 1971 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest) 1972 { 1973 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 1974 1975 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest); 1976 1977 EnterCriticalSection(&This->renderer.filter.csFilter); 1978 1979 if (source) 1980 This->source_rect = *source; 1981 if (dest) 1982 { 1983 This->target_rect = *dest; 1984 if (This->baseControlWindow.baseWindow.hWnd) 1985 { 1986 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest)); 1987 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left, 1988 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW); 1989 } 1990 } 1991 1992 LeaveCriticalSection(&This->renderer.filter.csFilter); 1993 1994 return S_OK; 1995 } 1996 1997 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest) 1998 { 1999 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2000 2001 if (source) 2002 *source = This->source_rect; 2003 2004 if (dest) 2005 *dest = This->target_rect; 2006 2007 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest); 2008 return S_OK; 2009 } 2010 2011 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode) 2012 { 2013 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2014 2015 FIXME("(%p/%p)->(...) stub\n", iface, This); 2016 return E_NOTIMPL; 2017 } 2018 2019 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode) 2020 { 2021 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2022 2023 FIXME("(%p/%p)->(...) stub\n", iface, This); 2024 return E_NOTIMPL; 2025 } 2026 2027 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd) 2028 { 2029 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2030 2031 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd); 2032 2033 EnterCriticalSection(&This->renderer.filter.csFilter); 2034 This->hWndClippingWindow = hwnd; 2035 VMR9_maybe_init(This, FALSE); 2036 if (!hwnd) 2037 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie); 2038 LeaveCriticalSection(&This->renderer.filter.csFilter); 2039 return S_OK; 2040 } 2041 2042 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc) 2043 { 2044 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2045 HRESULT hr; 2046 2047 FIXME("(%p/%p)->(...) semi-stub\n", iface, This); 2048 2049 EnterCriticalSection(&This->renderer.filter.csFilter); 2050 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd) 2051 { 2052 ERR("Not handling changing windows yet!!!\n"); 2053 LeaveCriticalSection(&This->renderer.filter.csFilter); 2054 return S_OK; 2055 } 2056 2057 if (!This->allocator_d3d9_dev) 2058 { 2059 ERR("No d3d9 device!\n"); 2060 LeaveCriticalSection(&This->renderer.filter.csFilter); 2061 return VFW_E_WRONG_STATE; 2062 } 2063 2064 /* Windowless extension */ 2065 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL); 2066 LeaveCriticalSection(&This->renderer.filter.csFilter); 2067 2068 return hr; 2069 } 2070 2071 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface) 2072 { 2073 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2074 2075 FIXME("(%p/%p)->(...) stub\n", iface, This); 2076 return E_NOTIMPL; 2077 } 2078 2079 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib) 2080 { 2081 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2082 2083 FIXME("(%p/%p)->(...) stub\n", iface, This); 2084 return E_NOTIMPL; 2085 } 2086 2087 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color) 2088 { 2089 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2090 2091 FIXME("(%p/%p)->(...) stub\n", iface, This); 2092 return E_NOTIMPL; 2093 } 2094 2095 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color) 2096 { 2097 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); 2098 2099 FIXME("(%p/%p)->(...) stub\n", iface, This); 2100 return E_NOTIMPL; 2101 } 2102 2103 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl = 2104 { 2105 VMR9WindowlessControl_QueryInterface, 2106 VMR9WindowlessControl_AddRef, 2107 VMR9WindowlessControl_Release, 2108 VMR9WindowlessControl_GetNativeVideoSize, 2109 VMR9WindowlessControl_GetMinIdealVideoSize, 2110 VMR9WindowlessControl_GetMaxIdealVideoSize, 2111 VMR9WindowlessControl_SetVideoPosition, 2112 VMR9WindowlessControl_GetVideoPosition, 2113 VMR9WindowlessControl_GetAspectRatioMode, 2114 VMR9WindowlessControl_SetAspectRatioMode, 2115 VMR9WindowlessControl_SetVideoClippingWindow, 2116 VMR9WindowlessControl_RepaintVideo, 2117 VMR9WindowlessControl_DisplayModeChanged, 2118 VMR9WindowlessControl_GetCurrentImage, 2119 VMR9WindowlessControl_SetBorderColor, 2120 VMR9WindowlessControl_GetBorderColor 2121 }; 2122 2123 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface, 2124 REFIID riid, LPVOID * ppv) 2125 { 2126 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2127 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 2128 } 2129 2130 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface) 2131 { 2132 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2133 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 2134 } 2135 2136 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface) 2137 { 2138 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2139 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 2140 } 2141 2142 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface, 2143 DWORD_PTR id, 2144 IVMRSurfaceAllocator *alloc) 2145 { 2146 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2147 2148 FIXME("(%p/%p)->(...) stub\n", iface, This); 2149 return E_NOTIMPL; 2150 } 2151 2152 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface, 2153 IDirectDraw7 *device, HMONITOR monitor) 2154 { 2155 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2156 2157 FIXME("(%p/%p)->(...) stub\n", iface, This); 2158 return E_NOTIMPL; 2159 } 2160 2161 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface, 2162 IDirectDraw7 *device, HMONITOR monitor) 2163 { 2164 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2165 2166 FIXME("(%p/%p)->(...) stub\n", iface, This); 2167 return E_NOTIMPL; 2168 } 2169 2170 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface) 2171 { 2172 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2173 2174 FIXME("(%p/%p)->(...) stub\n", iface, This); 2175 return E_NOTIMPL; 2176 } 2177 2178 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code, 2179 LONG_PTR param1, LONG_PTR param2) 2180 { 2181 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2182 2183 FIXME("(%p/%p)->(...) stub\n", iface, This); 2184 return E_NOTIMPL; 2185 } 2186 2187 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface, 2188 COLORREF clrBorder) 2189 { 2190 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface); 2191 2192 FIXME("(%p/%p)->(...) stub\n", iface, This); 2193 return E_NOTIMPL; 2194 } 2195 2196 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl = 2197 { 2198 VMR7SurfaceAllocatorNotify_QueryInterface, 2199 VMR7SurfaceAllocatorNotify_AddRef, 2200 VMR7SurfaceAllocatorNotify_Release, 2201 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator, 2202 VMR7SurfaceAllocatorNotify_SetDDrawDevice, 2203 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice, 2204 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces, 2205 VMR7SurfaceAllocatorNotify_NotifyEvent, 2206 VMR7SurfaceAllocatorNotify_SetBorderColor 2207 }; 2208 2209 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv) 2210 { 2211 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2212 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); 2213 } 2214 2215 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface) 2216 { 2217 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2218 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); 2219 } 2220 2221 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface) 2222 { 2223 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2224 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); 2225 } 2226 2227 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc) 2228 { 2229 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2230 2231 /* FIXME: This code is not tested!!! */ 2232 FIXME("(%p/%p)->(...) stub\n", iface, This); 2233 This->cookie = id; 2234 2235 if (This->presenter) 2236 return VFW_E_WRONG_STATE; 2237 2238 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter))) 2239 return E_NOINTERFACE; 2240 2241 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator))) 2242 This->allocator_is_ex = 1; 2243 else 2244 { 2245 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc; 2246 IVMRSurfaceAllocator9_AddRef(alloc); 2247 This->allocator_is_ex = 0; 2248 } 2249 2250 return S_OK; 2251 } 2252 2253 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor) 2254 { 2255 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2256 2257 FIXME("(%p/%p)->(...) semi-stub\n", iface, This); 2258 if (This->allocator_d3d9_dev) 2259 IDirect3DDevice9_Release(This->allocator_d3d9_dev); 2260 This->allocator_d3d9_dev = device; 2261 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev); 2262 This->allocator_mon = monitor; 2263 2264 return S_OK; 2265 } 2266 2267 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor) 2268 { 2269 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2270 2271 FIXME("(%p/%p)->(...) semi-stub\n", iface, This); 2272 if (This->allocator_d3d9_dev) 2273 IDirect3DDevice9_Release(This->allocator_d3d9_dev); 2274 This->allocator_d3d9_dev = device; 2275 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev); 2276 This->allocator_mon = monitor; 2277 2278 return S_OK; 2279 } 2280 2281 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface) 2282 { 2283 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2284 DWORD i; 2285 HRESULT hr = S_OK; 2286 2287 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface); 2288 2289 if (!allocinfo || !numbuffers || !surface) 2290 return E_POINTER; 2291 2292 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers) 2293 { 2294 ERR("Invalid number of buffers?\n"); 2295 return E_INVALIDARG; 2296 } 2297 2298 if (!This->allocator_d3d9_dev) 2299 { 2300 ERR("No direct3d device when requested to allocate a surface!\n"); 2301 return VFW_E_WRONG_STATE; 2302 } 2303 2304 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface) 2305 { 2306 ERR("Creating offscreen surface\n"); 2307 for (i = 0; i < *numbuffers; ++i) 2308 { 2309 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 2310 allocinfo->Format, allocinfo->Pool, &surface[i], NULL); 2311 if (FAILED(hr)) 2312 break; 2313 } 2314 } 2315 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface) 2316 { 2317 TRACE("Creating texture surface\n"); 2318 for (i = 0; i < *numbuffers; ++i) 2319 { 2320 IDirect3DTexture9 *texture; 2321 2322 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0, 2323 allocinfo->Format, allocinfo->Pool, &texture, NULL); 2324 if (FAILED(hr)) 2325 break; 2326 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]); 2327 IDirect3DTexture9_Release(texture); 2328 } 2329 } 2330 else 2331 { 2332 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags); 2333 return E_NOTIMPL; 2334 } 2335 2336 if (i >= allocinfo->MinBuffers) 2337 { 2338 hr = S_OK; 2339 *numbuffers = i; 2340 } 2341 else 2342 { 2343 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]); 2344 *numbuffers = 0; 2345 } 2346 return hr; 2347 } 2348 2349 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2) 2350 { 2351 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); 2352 2353 FIXME("(%p/%p)->(...) stub\n", iface, This); 2354 return E_NOTIMPL; 2355 } 2356 2357 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl = 2358 { 2359 VMR9SurfaceAllocatorNotify_QueryInterface, 2360 VMR9SurfaceAllocatorNotify_AddRef, 2361 VMR9SurfaceAllocatorNotify_Release, 2362 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator, 2363 VMR9SurfaceAllocatorNotify_SetD3DDevice, 2364 VMR9SurfaceAllocatorNotify_ChangeD3DDevice, 2365 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper, 2366 VMR9SurfaceAllocatorNotify_NotifyEvent 2367 }; 2368 2369 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid) 2370 { 2371 HRESULT hr; 2372 struct quartz_vmr* pVMR; 2373 2374 TRACE("(%p, %p)\n", outer_unk, ppv); 2375 2376 *ppv = NULL; 2377 2378 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr)); 2379 2380 pVMR->hD3d9 = LoadLibraryA("d3d9.dll"); 2381 if (!pVMR->hD3d9 ) 2382 { 2383 WARN("Could not load d3d9.dll\n"); 2384 CoTaskMemFree(pVMR); 2385 return VFW_E_DDRAW_CAPS_NOT_SUITABLE; 2386 } 2387 2388 pVMR->outer_unk = outer_unk; 2389 pVMR->bUnkOuterValid = FALSE; 2390 pVMR->bAggregatable = FALSE; 2391 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable; 2392 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl; 2393 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; 2394 2395 pVMR->mode = 0; 2396 pVMR->allocator_d3d9_dev = NULL; 2397 pVMR->allocator_mon= NULL; 2398 pVMR->num_surfaces = pVMR->cur_surface = 0; 2399 pVMR->allocator = NULL; 2400 pVMR->presenter = NULL; 2401 pVMR->hWndClippingWindow = NULL; 2402 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl; 2403 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl; 2404 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl; 2405 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl; 2406 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl; 2407 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl; 2408 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl; 2409 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl; 2410 2411 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer)) 2412 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer, 2413 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable); 2414 else 2415 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9, 2416 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable); 2417 2418 if (FAILED(hr)) 2419 goto fail; 2420 2421 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter, 2422 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin, 2423 &renderer_BaseWindowFuncTable); 2424 if (FAILED(hr)) 2425 goto fail; 2426 2427 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter, 2428 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin, 2429 &renderer_BaseControlVideoFuncTable); 2430 if (FAILED(hr)) 2431 goto fail; 2432 2433 *ppv = (LPVOID)pVMR; 2434 ZeroMemory(&pVMR->source_rect, sizeof(RECT)); 2435 ZeroMemory(&pVMR->target_rect, sizeof(RECT)); 2436 TRACE("Created at %p\n", pVMR); 2437 return hr; 2438 2439 fail: 2440 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface); 2441 FreeLibrary(pVMR->hD3d9); 2442 CoTaskMemFree(pVMR); 2443 return hr; 2444 } 2445 2446 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv) 2447 { 2448 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer); 2449 } 2450 2451 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv) 2452 { 2453 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9); 2454 } 2455 2456 2457 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv) 2458 { 2459 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2460 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); 2461 2462 *ppv = NULL; 2463 2464 if (IsEqualIID(riid, &IID_IUnknown)) 2465 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface); 2466 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9)) 2467 *ppv = &This->IVMRImagePresenter9_iface; 2468 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9)) 2469 *ppv = &This->IVMRSurfaceAllocatorEx9_iface; 2470 2471 if (*ppv) 2472 { 2473 IUnknown_AddRef((IUnknown *)(*ppv)); 2474 return S_OK; 2475 } 2476 2477 FIXME("No interface for %s\n", debugstr_guid(riid)); 2478 2479 return E_NOINTERFACE; 2480 } 2481 2482 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface) 2483 { 2484 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2485 ULONG refCount = InterlockedIncrement(&This->refCount); 2486 2487 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1); 2488 2489 return refCount; 2490 } 2491 2492 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface) 2493 { 2494 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2495 ULONG refCount = InterlockedDecrement(&This->refCount); 2496 2497 TRACE("(%p)->() Release from %d\n", iface, refCount + 1); 2498 2499 if (!refCount) 2500 { 2501 DWORD i; 2502 TRACE("Destroying\n"); 2503 CloseHandle(This->ack); 2504 IDirect3D9_Release(This->d3d9_ptr); 2505 2506 TRACE("Number of surfaces: %u\n", This->num_surfaces); 2507 for (i = 0; i < This->num_surfaces; ++i) 2508 { 2509 IDirect3DSurface9 *surface = This->d3d9_surfaces[i]; 2510 TRACE("Releasing surface %p\n", surface); 2511 if (surface) 2512 IDirect3DSurface9_Release(surface); 2513 } 2514 2515 CoTaskMemFree(This->d3d9_surfaces); 2516 This->d3d9_surfaces = NULL; 2517 This->num_surfaces = 0; 2518 if (This->d3d9_vertex) 2519 { 2520 IDirect3DVertexBuffer9_Release(This->d3d9_vertex); 2521 This->d3d9_vertex = NULL; 2522 } 2523 CoTaskMemFree(This); 2524 return 0; 2525 } 2526 return refCount; 2527 } 2528 2529 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id) 2530 { 2531 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2532 2533 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9); 2534 return S_OK; 2535 } 2536 2537 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id) 2538 { 2539 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2540 2541 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9); 2542 return S_OK; 2543 } 2544 2545 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1) 2546 struct VERTEX { float x, y, z, rhw, u, v; }; 2547 2548 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface) 2549 { 2550 IDirect3DTexture9 *texture = NULL; 2551 HRESULT hr; 2552 2553 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF); 2554 if (FAILED(hr)) 2555 { 2556 FIXME("SetFVF: %08x\n", hr); 2557 return hr; 2558 } 2559 2560 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX)); 2561 if (FAILED(hr)) 2562 { 2563 FIXME("SetStreamSource: %08x\n", hr); 2564 return hr; 2565 } 2566 2567 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture); 2568 if (FAILED(hr)) 2569 { 2570 FIXME("IDirect3DSurface9_GetContainer failed\n"); 2571 return hr; 2572 } 2573 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture); 2574 IDirect3DTexture9_Release(texture); 2575 if (FAILED(hr)) 2576 { 2577 FIXME("SetTexture: %08x\n", hr); 2578 return hr; 2579 } 2580 2581 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2); 2582 if (FAILED(hr)) 2583 { 2584 FIXME("DrawPrimitive: %08x\n", hr); 2585 return hr; 2586 } 2587 2588 return S_OK; 2589 } 2590 2591 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface) 2592 { 2593 HRESULT hr; 2594 IDirect3DSurface9 *target = NULL; 2595 RECT target_rect; 2596 2597 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target); 2598 if (FAILED(hr)) 2599 { 2600 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr); 2601 return hr; 2602 } 2603 2604 /* Move rect to origin and flip it */ 2605 SetRect(&target_rect, 0, This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top, 2606 This->pVMR9->target_rect.right - This->pVMR9->target_rect.left, 0); 2607 2608 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR); 2609 if (FAILED(hr)) 2610 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr); 2611 IDirect3DSurface9_Release(target); 2612 2613 return hr; 2614 } 2615 2616 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info) 2617 { 2618 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); 2619 HRESULT hr; 2620 RECT output; 2621 BOOL render = FALSE; 2622 2623 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9); 2624 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output); 2625 TRACE("Output rectangle: %s\n", wine_dbgstr_rect(&output)); 2626 2627 /* This might happen if we don't have active focus (eg on a different virtual desktop) */ 2628 if (!This->d3d9_dev) 2629 return S_OK; 2630 2631 /* Display image here */ 2632 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 2633 if (FAILED(hr)) 2634 FIXME("hr: %08x\n", hr); 2635 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev); 2636 if (SUCCEEDED(hr)) 2637 { 2638 if (This->d3d9_vertex) 2639 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf); 2640 else 2641 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf); 2642 render = SUCCEEDED(hr); 2643 } 2644 else 2645 FIXME("BeginScene: %08x\n", hr); 2646 hr = IDirect3DDevice9_EndScene(This->d3d9_dev); 2647 if (render && SUCCEEDED(hr)) 2648 { 2649 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL); 2650 if (FAILED(hr)) 2651 FIXME("Presenting image: %08x\n", hr); 2652 } 2653 2654 return S_OK; 2655 } 2656 2657 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter = 2658 { 2659 VMR9_ImagePresenter_QueryInterface, 2660 VMR9_ImagePresenter_AddRef, 2661 VMR9_ImagePresenter_Release, 2662 VMR9_ImagePresenter_StartPresenting, 2663 VMR9_ImagePresenter_StopPresenting, 2664 VMR9_ImagePresenter_PresentImage 2665 }; 2666 2667 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv) 2668 { 2669 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 2670 2671 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv); 2672 } 2673 2674 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface) 2675 { 2676 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 2677 2678 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface); 2679 } 2680 2681 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface) 2682 { 2683 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 2684 2685 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface); 2686 } 2687 2688 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo) 2689 { 2690 D3DCAPS9 caps; 2691 UINT width, height; 2692 HRESULT hr; 2693 2694 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)) 2695 /* Only needed for texture surfaces */ 2696 return S_OK; 2697 2698 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps); 2699 if (FAILED(hr)) 2700 return hr; 2701 2702 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) 2703 { 2704 width = allocinfo->dwWidth; 2705 height = allocinfo->dwHeight; 2706 } 2707 else 2708 { 2709 width = height = 1; 2710 while (width < allocinfo->dwWidth) 2711 width *= 2; 2712 2713 while (height < allocinfo->dwHeight) 2714 height *= 2; 2715 FIXME("NPOW2 support missing, not using proper surfaces!\n"); 2716 } 2717 2718 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) 2719 { 2720 if (height > width) 2721 width = height; 2722 else 2723 height = width; 2724 FIXME("Square texture support required..\n"); 2725 } 2726 2727 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL); 2728 if (FAILED(hr)) 2729 { 2730 ERR("Couldn't create vertex buffer: %08x\n", hr); 2731 return hr; 2732 } 2733 2734 This->reset = TRUE; 2735 allocinfo->dwHeight = height; 2736 allocinfo->dwWidth = width; 2737 2738 return hr; 2739 } 2740 2741 static DWORD WINAPI MessageLoop(LPVOID lpParameter) 2742 { 2743 MSG msg; 2744 BOOL fGotMessage; 2745 VMR9DefaultAllocatorPresenterImpl *This = lpParameter; 2746 2747 TRACE("Starting message loop\n"); 2748 2749 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow))) 2750 { 2751 FIXME("Failed to prepare window\n"); 2752 return FALSE; 2753 } 2754 2755 SetEvent(This->ack); 2756 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1) 2757 { 2758 TranslateMessage(&msg); 2759 DispatchMessageW(&msg); 2760 } 2761 2762 TRACE("End of message loop\n"); 2763 2764 return 0; 2765 } 2766 2767 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out) 2768 { 2769 UINT d3d9_adapter; 2770 HMONITOR mon; 2771 2772 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL); 2773 if (!mon) 2774 d3d9_adapter = 0; 2775 else 2776 { 2777 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter) 2778 { 2779 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter)) 2780 break; 2781 } 2782 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9)) 2783 d3d9_adapter = 0; 2784 } 2785 if (mon_out) 2786 *mon_out = mon; 2787 return d3d9_adapter; 2788 } 2789 2790 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers) 2791 { 2792 D3DPRESENT_PARAMETERS d3dpp; 2793 DWORD d3d9_adapter; 2794 HRESULT hr; 2795 2796 TRACE("(%p)->()\n", This); 2797 2798 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid); 2799 if (!This->hWndThread) 2800 return FALSE; 2801 2802 WaitForSingleObject(This->ack, INFINITE); 2803 2804 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE; 2805 2806 /* Obtain a monitor and d3d9 device */ 2807 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon); 2808 2809 /* Now try to create the d3d9 device */ 2810 ZeroMemory(&d3dpp, sizeof(d3dpp)); 2811 d3dpp.Windowed = TRUE; 2812 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd; 2813 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 2814 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top; 2815 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left; 2816 2817 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); 2818 if (FAILED(hr)) 2819 { 2820 ERR("Could not create device: %08x\n", hr); 2821 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); 2822 return FALSE; 2823 } 2824 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon); 2825 2826 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *)); 2827 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *)); 2828 2829 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info); 2830 if (FAILED(hr)) 2831 ERR("Setting allocation settings failed: %08x\n", hr); 2832 2833 if (SUCCEEDED(hr)) 2834 { 2835 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces); 2836 if (FAILED(hr)) 2837 ERR("Allocating surfaces failed: %08x\n", hr); 2838 } 2839 2840 if (FAILED(hr)) 2841 { 2842 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie); 2843 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); 2844 return FALSE; 2845 } 2846 2847 This->num_surfaces = *numbuffers; 2848 2849 return TRUE; 2850 } 2851 2852 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers) 2853 { 2854 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 2855 2856 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow) 2857 { 2858 ERR("No window set\n"); 2859 return VFW_E_WRONG_STATE; 2860 } 2861 2862 This->info = *allocinfo; 2863 2864 if (!CreateRenderingWindow(This, allocinfo, numbuffers)) 2865 { 2866 ERR("Failed to create rendering window, expect no output!\n"); 2867 return VFW_E_WRONG_STATE; 2868 } 2869 2870 return S_OK; 2871 } 2872 2873 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id) 2874 { 2875 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 2876 2877 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) 2878 { 2879 return S_OK; 2880 } 2881 2882 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0); 2883 PostThreadMessageW(This->tid, WM_QUIT, 0, 0); 2884 WaitForSingleObject(This->hWndThread, INFINITE); 2885 This->hWndThread = NULL; 2886 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); 2887 2888 return S_OK; 2889 } 2890 2891 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */ 2892 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This) 2893 { 2894 struct VERTEX t_vert[4]; 2895 UINT width, height; 2896 unsigned int i; 2897 void *bits = NULL; 2898 D3DPRESENT_PARAMETERS d3dpp; 2899 HRESULT hr; 2900 2901 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) 2902 { 2903 ERR("No window\n"); 2904 return E_FAIL; 2905 } 2906 2907 if (!This->d3d9_surfaces || !This->reset) 2908 return S_OK; 2909 2910 This->reset = FALSE; 2911 TRACE("RESETTING\n"); 2912 if (This->d3d9_vertex) 2913 { 2914 IDirect3DVertexBuffer9_Release(This->d3d9_vertex); 2915 This->d3d9_vertex = NULL; 2916 } 2917 2918 for (i = 0; i < This->num_surfaces; ++i) 2919 { 2920 IDirect3DSurface9 *surface = This->d3d9_surfaces[i]; 2921 TRACE("Releasing surface %p\n", surface); 2922 if (surface) 2923 IDirect3DSurface9_Release(surface); 2924 } 2925 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces); 2926 2927 /* Now try to create the d3d9 device */ 2928 ZeroMemory(&d3dpp, sizeof(d3dpp)); 2929 d3dpp.Windowed = TRUE; 2930 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd; 2931 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 2932 2933 if (This->d3d9_dev) 2934 IDirect3DDevice9_Release(This->d3d9_dev); 2935 This->d3d9_dev = NULL; 2936 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); 2937 if (FAILED(hr)) 2938 { 2939 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); 2940 if (FAILED(hr)) 2941 { 2942 ERR("--> Creating device: %08x\n", hr); 2943 return S_OK; 2944 } 2945 } 2946 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon); 2947 2948 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces); 2949 2950 This->reset = FALSE; 2951 2952 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface)) 2953 return S_OK; 2954 2955 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, 2956 This->info.Pool, &This->d3d9_vertex, NULL); 2957 2958 width = This->info.dwWidth; 2959 height = This->info.dwHeight; 2960 2961 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i) 2962 { 2963 if (i % 2) 2964 { 2965 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f; 2966 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width; 2967 } 2968 else 2969 { 2970 t_vert[i].x = -0.5f; 2971 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width; 2972 } 2973 2974 if (i % 4 < 2) 2975 { 2976 t_vert[i].y = -0.5f; 2977 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height; 2978 } 2979 else 2980 { 2981 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f; 2982 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height; 2983 } 2984 t_vert[i].z = 0.0f; 2985 t_vert[i].rhw = 1.0f; 2986 } 2987 2988 FIXME("Vertex rectangle:\n"); 2989 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y); 2990 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y); 2991 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v); 2992 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v); 2993 2994 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0); 2995 memcpy(bits, t_vert, sizeof(t_vert)); 2996 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex); 2997 2998 return S_OK; 2999 } 3000 3001 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface) 3002 { 3003 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 3004 3005 /* Update everything first, this is needed because the surface might be destroyed in the reset */ 3006 if (!This->d3d9_dev) 3007 { 3008 TRACE("Device has left me!\n"); 3009 return E_FAIL; 3010 } 3011 3012 VMR9_SurfaceAllocator_UpdateDeviceReset(This); 3013 3014 if (surfaceindex >= This->num_surfaces) 3015 { 3016 ERR("surfaceindex is greater than num_surfaces\n"); 3017 return E_FAIL; 3018 } 3019 *surface = This->d3d9_surfaces[surfaceindex]; 3020 IDirect3DSurface9_AddRef(*surface); 3021 3022 return S_OK; 3023 } 3024 3025 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify) 3026 { 3027 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); 3028 3029 TRACE("(%p/%p)->(...)\n", iface, This); 3030 3031 /* No AddRef taken here or the base VMR9 filter would never be destroyed */ 3032 This->SurfaceAllocatorNotify = allocnotify; 3033 return S_OK; 3034 } 3035 3036 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator = 3037 { 3038 VMR9_SurfaceAllocator_QueryInterface, 3039 VMR9_SurfaceAllocator_AddRef, 3040 VMR9_SurfaceAllocator_Release, 3041 VMR9_SurfaceAllocator_InitializeDevice, 3042 VMR9_SurfaceAllocator_TerminateDevice, 3043 VMR9_SurfaceAllocator_GetSurface, 3044 VMR9_SurfaceAllocator_AdviseNotify, 3045 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */ 3046 }; 3047 3048 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle) 3049 { 3050 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion); 3051 3052 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9"); 3053 if (!d3d9_create) return NULL; 3054 3055 return d3d9_create(D3D_SDK_VERSION); 3056 } 3057 3058 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv) 3059 { 3060 HRESULT hr = S_OK; 3061 int i; 3062 VMR9DefaultAllocatorPresenterImpl* This; 3063 3064 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl)); 3065 if (!This) 3066 return E_OUTOFMEMORY; 3067 3068 This->d3d9_ptr = init_d3d9(parent->hD3d9); 3069 if (!This->d3d9_ptr) 3070 { 3071 WARN("Could not initialize d3d9.dll\n"); 3072 CoTaskMemFree(This); 3073 return VFW_E_DDRAW_CAPS_NOT_SUITABLE; 3074 } 3075 3076 i = 0; 3077 do 3078 { 3079 D3DDISPLAYMODE mode; 3080 3081 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode); 3082 if (hr == D3DERR_INVALIDCALL) break; /* out of adapters */ 3083 } while (FAILED(hr)); 3084 if (FAILED(hr)) 3085 ERR("HR: %08x\n", hr); 3086 if (hr == D3DERR_NOTAVAILABLE) 3087 { 3088 ERR("Format not supported\n"); 3089 IDirect3D9_Release(This->d3d9_ptr); 3090 CoTaskMemFree(This); 3091 return VFW_E_DDRAW_CAPS_NOT_SUITABLE; 3092 } 3093 3094 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter; 3095 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator; 3096 3097 This->refCount = 1; 3098 This->pVMR9 = parent; 3099 This->d3d9_surfaces = NULL; 3100 This->d3d9_dev = NULL; 3101 This->hMon = 0; 3102 This->d3d9_vertex = NULL; 3103 This->num_surfaces = 0; 3104 This->hWndThread = NULL; 3105 This->ack = CreateEventW(NULL, 0, 0, NULL); 3106 This->SurfaceAllocatorNotify = NULL; 3107 This->reset = FALSE; 3108 3109 *ppv = &This->IVMRImagePresenter9_iface; 3110 return S_OK; 3111 } 3112