Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvideorenderer.c
Go to the documentation of this file.
00001 /* 00002 * Video Renderer (Fullscreen and Windowed using Direct Draw) 00003 * 00004 * Copyright 2004 Christian Costa 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #define NONAMELESSSTRUCT 00024 #define NONAMELESSUNION 00025 #include "quartz_private.h" 00026 #include "control_private.h" 00027 #include "pin.h" 00028 00029 #include "uuids.h" 00030 #include "vfwmsgs.h" 00031 #include "amvideo.h" 00032 #include "windef.h" 00033 #include "winbase.h" 00034 #include "dshow.h" 00035 #include "evcode.h" 00036 #include "strmif.h" 00037 #include "ddraw.h" 00038 #include "dvdmedia.h" 00039 00040 #include <assert.h> 00041 #include "wine/unicode.h" 00042 #include "wine/debug.h" 00043 00044 WINE_DEFAULT_DEBUG_CHANNEL(quartz); 00045 00046 static BOOL wnd_class_registered = FALSE; 00047 00048 static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; 00049 00050 static const IBaseFilterVtbl VideoRenderer_Vtbl; 00051 static const IUnknownVtbl IInner_VTable; 00052 static const IBasicVideoVtbl IBasicVideo_VTable; 00053 static const IVideoWindowVtbl IVideoWindow_VTable; 00054 static const IPinVtbl VideoRenderer_InputPin_Vtbl; 00055 00056 typedef struct VideoRendererImpl 00057 { 00058 const IBaseFilterVtbl * lpVtbl; 00059 const IBasicVideoVtbl * IBasicVideo_vtbl; 00060 const IVideoWindowVtbl * IVideoWindow_vtbl; 00061 const IUnknownVtbl * IInner_vtbl; 00062 00063 LONG refCount; 00064 CRITICAL_SECTION csFilter; 00065 FILTER_STATE state; 00066 REFERENCE_TIME rtStreamStart; 00067 IReferenceClock * pClock; 00068 FILTER_INFO filterInfo; 00069 00070 InputPin *pInputPin; 00071 00072 BOOL init; 00073 HANDLE hThread; 00074 HANDLE blocked; 00075 00076 DWORD ThreadID; 00077 HANDLE hEvent; 00078 BOOL ThreadResult; 00079 HWND hWnd; 00080 HWND hWndMsgDrain; 00081 BOOL AutoShow; 00082 RECT SourceRect; 00083 RECT DestRect; 00084 RECT WindowPos; 00085 LONG VideoWidth; 00086 LONG VideoHeight; 00087 IUnknown * pUnkOuter; 00088 BOOL bUnkOuterValid; 00089 BOOL bAggregatable; 00090 REFERENCE_TIME rtLastStop; 00091 MediaSeekingImpl mediaSeeking; 00092 00093 /* During pause we can hold a single sample, for use in GetCurrentImage */ 00094 IMediaSample *sample_held; 00095 } VideoRendererImpl; 00096 00097 static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 00098 { 00099 VideoRendererImpl* pVideoRenderer = (VideoRendererImpl*)GetWindowLongPtrW(hwnd, 0); 00100 LPRECT lprect = (LPRECT)lParam; 00101 00102 if (pVideoRenderer && pVideoRenderer->hWndMsgDrain) 00103 { 00104 switch(uMsg) 00105 { 00106 case WM_KEYDOWN: 00107 case WM_KEYUP: 00108 case WM_LBUTTONDBLCLK: 00109 case WM_LBUTTONDOWN: 00110 case WM_LBUTTONUP: 00111 case WM_MBUTTONDBLCLK: 00112 case WM_MBUTTONDOWN: 00113 case WM_MBUTTONUP: 00114 case WM_MOUSEACTIVATE: 00115 case WM_MOUSEMOVE: 00116 case WM_NCLBUTTONDBLCLK: 00117 case WM_NCLBUTTONDOWN: 00118 case WM_NCLBUTTONUP: 00119 case WM_NCMBUTTONDBLCLK: 00120 case WM_NCMBUTTONDOWN: 00121 case WM_NCMBUTTONUP: 00122 case WM_NCMOUSEMOVE: 00123 case WM_NCRBUTTONDBLCLK: 00124 case WM_NCRBUTTONDOWN: 00125 case WM_NCRBUTTONUP: 00126 case WM_RBUTTONDBLCLK: 00127 case WM_RBUTTONDOWN: 00128 case WM_RBUTTONUP: 00129 PostMessageA(pVideoRenderer->hWndMsgDrain, uMsg, wParam, lParam); 00130 break; 00131 default: 00132 break; 00133 } 00134 } 00135 00136 switch(uMsg) 00137 { 00138 case WM_SIZING: 00139 /* TRACE("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); */ 00140 SetWindowPos(hwnd, NULL, lprect->left, lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top, SWP_NOZORDER); 00141 GetClientRect(hwnd, &pVideoRenderer->DestRect); 00142 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", 00143 pVideoRenderer->DestRect.left, 00144 pVideoRenderer->DestRect.top, 00145 pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left, 00146 pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top); 00147 return TRUE; 00148 case WM_SIZE: 00149 TRACE("WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam)); 00150 GetClientRect(hwnd, &pVideoRenderer->DestRect); 00151 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", 00152 pVideoRenderer->DestRect.left, 00153 pVideoRenderer->DestRect.top, 00154 pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left, 00155 pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top); 00156 return TRUE; 00157 default: 00158 return DefWindowProcA(hwnd, uMsg, wParam, lParam); 00159 } 00160 return 0; 00161 } 00162 00163 static BOOL CreateRenderingWindow(VideoRendererImpl* This) 00164 { 00165 WNDCLASSA winclass; 00166 00167 TRACE("(%p)->()\n", This); 00168 00169 winclass.style = 0; 00170 winclass.lpfnWndProc = VideoWndProcA; 00171 winclass.cbClsExtra = 0; 00172 winclass.cbWndExtra = sizeof(VideoRendererImpl*); 00173 winclass.hInstance = NULL; 00174 winclass.hIcon = NULL; 00175 winclass.hCursor = NULL; 00176 winclass.hbrBackground = GetStockObject(BLACK_BRUSH); 00177 winclass.lpszMenuName = NULL; 00178 winclass.lpszClassName = "Wine ActiveMovie Class"; 00179 00180 if (!wnd_class_registered) 00181 { 00182 if (!RegisterClassA(&winclass)) 00183 { 00184 ERR("Unable to register window %u\n", GetLastError()); 00185 return FALSE; 00186 } 00187 wnd_class_registered = TRUE; 00188 } 00189 00190 This->hWnd = CreateWindowExA(0, "Wine ActiveMovie Class", "Wine ActiveMovie Window", WS_SIZEBOX, 00191 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 00192 NULL, NULL, NULL); 00193 00194 if (!This->hWnd) 00195 { 00196 ERR("Unable to create window\n"); 00197 return FALSE; 00198 } 00199 00200 SetWindowLongPtrW(This->hWnd, 0, (LONG_PTR)This); 00201 00202 return TRUE; 00203 } 00204 00205 static DWORD WINAPI MessageLoop(LPVOID lpParameter) 00206 { 00207 VideoRendererImpl* This = lpParameter; 00208 MSG msg; 00209 BOOL fGotMessage; 00210 00211 TRACE("Starting message loop\n"); 00212 00213 if (!CreateRenderingWindow(This)) 00214 { 00215 This->ThreadResult = FALSE; 00216 SetEvent(This->hEvent); 00217 return 0; 00218 } 00219 00220 This->ThreadResult = TRUE; 00221 SetEvent(This->hEvent); 00222 00223 while ((fGotMessage = GetMessageA(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1) 00224 { 00225 TranslateMessage(&msg); 00226 DispatchMessageA(&msg); 00227 } 00228 00229 TRACE("End of message loop\n"); 00230 00231 return msg.wParam; 00232 } 00233 00234 static BOOL CreateRenderingSubsystem(VideoRendererImpl* This) 00235 { 00236 This->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 00237 if (!This->hEvent) 00238 return FALSE; 00239 00240 This->hThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->ThreadID); 00241 if (!This->hThread) 00242 { 00243 CloseHandle(This->hEvent); 00244 return FALSE; 00245 } 00246 00247 WaitForSingleObject(This->hEvent, INFINITE); 00248 00249 if (!This->ThreadResult) 00250 { 00251 CloseHandle(This->hEvent); 00252 CloseHandle(This->hThread); 00253 return FALSE; 00254 } 00255 00256 return TRUE; 00257 } 00258 00259 static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size) 00260 { 00261 AM_MEDIA_TYPE amt; 00262 HRESULT hr = S_OK; 00263 DDSURFACEDESC sdesc; 00264 HDC hDC; 00265 BITMAPINFOHEADER *bmiHeader; 00266 00267 TRACE("(%p)->(%p, %d)\n", This, data, size); 00268 00269 sdesc.dwSize = sizeof(sdesc); 00270 hr = IPin_ConnectionMediaType((IPin *)This->pInputPin, &amt); 00271 if (FAILED(hr)) { 00272 ERR("Unable to retrieve media type\n"); 00273 return hr; 00274 } 00275 00276 if (IsEqualIID(&amt.formattype, &FORMAT_VideoInfo)) 00277 { 00278 bmiHeader = &((VIDEOINFOHEADER *)amt.pbFormat)->bmiHeader; 00279 } 00280 else if (IsEqualIID(&amt.formattype, &FORMAT_VideoInfo2)) 00281 { 00282 bmiHeader = &((VIDEOINFOHEADER2 *)amt.pbFormat)->bmiHeader; 00283 } 00284 else 00285 { 00286 FIXME("Unknown type %s\n", debugstr_guid(&amt.subtype)); 00287 return VFW_E_RUNTIME_ERROR; 00288 } 00289 00290 TRACE("biSize = %d\n", bmiHeader->biSize); 00291 TRACE("biWidth = %d\n", bmiHeader->biWidth); 00292 TRACE("biHeight = %d\n", bmiHeader->biHeight); 00293 TRACE("biPlanes = %d\n", bmiHeader->biPlanes); 00294 TRACE("biBitCount = %d\n", bmiHeader->biBitCount); 00295 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4)); 00296 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage); 00297 00298 if (!This->init) 00299 { 00300 DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE); 00301 DWORD style_ex = GetWindowLongW(This->hWnd, GWL_EXSTYLE); 00302 00303 if (!This->WindowPos.right || !This->WindowPos.bottom) 00304 This->WindowPos = This->SourceRect; 00305 00306 AdjustWindowRectEx(&This->WindowPos, style, TRUE, style_ex); 00307 00308 TRACE("WindowPos: %d %d %d %d\n", This->WindowPos.left, This->WindowPos.top, This->WindowPos.right, This->WindowPos.bottom); 00309 SetWindowPos(This->hWnd, NULL, 00310 This->WindowPos.left, 00311 This->WindowPos.top, 00312 This->WindowPos.right - This->WindowPos.left, 00313 This->WindowPos.bottom - This->WindowPos.top, 00314 SWP_NOZORDER|SWP_NOMOVE); 00315 00316 GetClientRect(This->hWnd, &This->DestRect); 00317 This->init = TRUE; 00318 } 00319 00320 hDC = GetDC(This->hWnd); 00321 00322 if (!hDC) { 00323 ERR("Cannot get DC from window!\n"); 00324 return E_FAIL; 00325 } 00326 00327 TRACE("Src Rect: %d %d %d %d\n", This->SourceRect.left, This->SourceRect.top, This->SourceRect.right, This->SourceRect.bottom); 00328 TRACE("Dst Rect: %d %d %d %d\n", This->DestRect.left, This->DestRect.top, This->DestRect.right, This->DestRect.bottom); 00329 00330 StretchDIBits(hDC, This->DestRect.left, This->DestRect.top, This->DestRect.right -This->DestRect.left, 00331 This->DestRect.bottom - This->DestRect.top, This->SourceRect.left, This->SourceRect.top, 00332 This->SourceRect.right - This->SourceRect.left, This->SourceRect.bottom - This->SourceRect.top, 00333 data, (BITMAPINFO *)bmiHeader, DIB_RGB_COLORS, SRCCOPY); 00334 00335 ReleaseDC(This->hWnd, hDC); 00336 if (This->AutoShow) 00337 ShowWindow(This->hWnd, SW_SHOW); 00338 00339 return S_OK; 00340 } 00341 00342 static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) 00343 { 00344 VideoRendererImpl *This = iface; 00345 LPBYTE pbSrcStream = NULL; 00346 LONG cbSrcStream = 0; 00347 REFERENCE_TIME tStart, tStop; 00348 HRESULT hr; 00349 00350 TRACE("(%p)->(%p)\n", iface, pSample); 00351 00352 EnterCriticalSection(&This->csFilter); 00353 00354 if (This->pInputPin->flushing || This->pInputPin->end_of_stream) 00355 { 00356 LeaveCriticalSection(&This->csFilter); 00357 return S_FALSE; 00358 } 00359 00360 if (This->state == State_Stopped) 00361 { 00362 LeaveCriticalSection(&This->csFilter); 00363 return VFW_E_WRONG_STATE; 00364 } 00365 00366 hr = IMediaSample_GetTime(pSample, &tStart, &tStop); 00367 if (FAILED(hr)) 00368 ERR("Cannot get sample time (%x)\n", hr); 00369 00370 if (This->rtLastStop != tStart) 00371 { 00372 if (IMediaSample_IsDiscontinuity(pSample) == S_FALSE) 00373 ERR("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n", 00374 (DWORD)(This->rtLastStop / 10000000), 00375 (DWORD)((This->rtLastStop / 10000)%1000), 00376 (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000)); 00377 This->rtLastStop = tStart; 00378 } 00379 00380 /* Preroll means the sample isn't shown, this is used for key frames and things like that */ 00381 if (IMediaSample_IsPreroll(pSample) == S_OK) 00382 { 00383 This->rtLastStop = tStop; 00384 LeaveCriticalSection(&This->csFilter); 00385 return S_OK; 00386 } 00387 00388 hr = IMediaSample_GetPointer(pSample, &pbSrcStream); 00389 if (FAILED(hr)) 00390 { 00391 ERR("Cannot get pointer to sample data (%x)\n", hr); 00392 LeaveCriticalSection(&This->csFilter); 00393 return hr; 00394 } 00395 00396 cbSrcStream = IMediaSample_GetActualDataLength(pSample); 00397 00398 TRACE("val %p %d\n", pbSrcStream, cbSrcStream); 00399 00400 #if 0 /* For debugging purpose */ 00401 { 00402 int i; 00403 for(i = 0; i < cbSrcStream; i++) 00404 { 00405 if ((i!=0) && !(i%16)) 00406 TRACE("\n"); 00407 TRACE("%02x ", pbSrcStream[i]); 00408 } 00409 TRACE("\n"); 00410 } 00411 #endif 00412 00413 SetEvent(This->hEvent); 00414 if (This->state == State_Paused) 00415 { 00416 This->sample_held = pSample; 00417 LeaveCriticalSection(&This->csFilter); 00418 WaitForSingleObject(This->blocked, INFINITE); 00419 EnterCriticalSection(&This->csFilter); 00420 This->sample_held = NULL; 00421 if (This->state == State_Paused) 00422 { 00423 /* Flushing */ 00424 LeaveCriticalSection(&This->csFilter); 00425 return S_OK; 00426 } 00427 if (This->state == State_Stopped) 00428 { 00429 LeaveCriticalSection(&This->csFilter); 00430 return VFW_E_WRONG_STATE; 00431 } 00432 } 00433 00434 if (This->pClock && This->state == State_Running) 00435 { 00436 REFERENCE_TIME time, trefstart, trefstop; 00437 LONG delta; 00438 00439 /* Perhaps I <SHOULD> use the reference clock AdviseTime function here 00440 * I'm not going to! When I tried, it seemed to generate lag and 00441 * it caused instability. 00442 */ 00443 IReferenceClock_GetTime(This->pClock, &time); 00444 00445 trefstart = This->rtStreamStart; 00446 trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->rtStreamStart; 00447 delta = (LONG)((trefstart-time)/10000); 00448 This->rtStreamStart = trefstop; 00449 This->rtLastStop = tStop; 00450 00451 if (delta > 0) 00452 { 00453 TRACE("Sleeping for %u ms\n", delta); 00454 Sleep(delta); 00455 } 00456 else if (time > trefstop) 00457 { 00458 TRACE("Dropping sample: Time: %u.%03u ms trefstop: %u.%03u ms!\n", 00459 (DWORD)(time / 10000000), (DWORD)((time / 10000)%1000), 00460 (DWORD)(trefstop / 10000000), (DWORD)((trefstop / 10000)%1000) ); 00461 This->rtLastStop = tStop; 00462 LeaveCriticalSection(&This->csFilter); 00463 return S_OK; 00464 } 00465 } 00466 This->rtLastStop = tStop; 00467 00468 VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); 00469 00470 LeaveCriticalSection(&This->csFilter); 00471 return S_OK; 00472 } 00473 00474 static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) 00475 { 00476 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) 00477 return S_FALSE; 00478 00479 if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32) || 00480 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24) || 00481 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565) || 00482 IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)) 00483 { 00484 VideoRendererImpl* This = iface; 00485 LONG height; 00486 00487 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) 00488 { 00489 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat; 00490 This->SourceRect.left = 0; 00491 This->SourceRect.top = 0; 00492 This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth; 00493 height = format->bmiHeader.biHeight; 00494 if (height < 0) 00495 This->SourceRect.bottom = This->VideoHeight = -height; 00496 else 00497 This->SourceRect.bottom = This->VideoHeight = height; 00498 } 00499 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) 00500 { 00501 VIDEOINFOHEADER2 *format2 = (VIDEOINFOHEADER2 *)pmt->pbFormat; 00502 00503 This->SourceRect.left = 0; 00504 This->SourceRect.top = 0; 00505 This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth; 00506 height = format2->bmiHeader.biHeight; 00507 if (height < 0) 00508 This->SourceRect.bottom = This->VideoHeight = -height; 00509 else 00510 This->SourceRect.bottom = This->VideoHeight = height; 00511 } 00512 else 00513 { 00514 WARN("Format type %s not supported\n", debugstr_guid(&pmt->formattype)); 00515 return S_FALSE; 00516 } 00517 return S_OK; 00518 } 00519 return S_FALSE; 00520 } 00521 00522 static inline VideoRendererImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) 00523 { 00524 return (VideoRendererImpl *)((char*)iface - FIELD_OFFSET(VideoRendererImpl, mediaSeeking.lpVtbl)); 00525 } 00526 00527 static HRESULT WINAPI VideoRendererImpl_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) 00528 { 00529 VideoRendererImpl *This = impl_from_IMediaSeeking(iface); 00530 00531 return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); 00532 } 00533 00534 static ULONG WINAPI VideoRendererImpl_Seeking_AddRef(IMediaSeeking * iface) 00535 { 00536 VideoRendererImpl *This = impl_from_IMediaSeeking(iface); 00537 00538 return IUnknown_AddRef((IUnknown *)This); 00539 } 00540 00541 static ULONG WINAPI VideoRendererImpl_Seeking_Release(IMediaSeeking * iface) 00542 { 00543 VideoRendererImpl *This = impl_from_IMediaSeeking(iface); 00544 00545 return IUnknown_Release((IUnknown *)This); 00546 } 00547 00548 static const IMediaSeekingVtbl VideoRendererImpl_Seeking_Vtbl = 00549 { 00550 VideoRendererImpl_Seeking_QueryInterface, 00551 VideoRendererImpl_Seeking_AddRef, 00552 VideoRendererImpl_Seeking_Release, 00553 MediaSeekingImpl_GetCapabilities, 00554 MediaSeekingImpl_CheckCapabilities, 00555 MediaSeekingImpl_IsFormatSupported, 00556 MediaSeekingImpl_QueryPreferredFormat, 00557 MediaSeekingImpl_GetTimeFormat, 00558 MediaSeekingImpl_IsUsingTimeFormat, 00559 MediaSeekingImpl_SetTimeFormat, 00560 MediaSeekingImpl_GetDuration, 00561 MediaSeekingImpl_GetStopPosition, 00562 MediaSeekingImpl_GetCurrentPosition, 00563 MediaSeekingImpl_ConvertTimeFormat, 00564 MediaSeekingImpl_SetPositions, 00565 MediaSeekingImpl_GetPositions, 00566 MediaSeekingImpl_GetAvailable, 00567 MediaSeekingImpl_SetRate, 00568 MediaSeekingImpl_GetRate, 00569 MediaSeekingImpl_GetPreroll 00570 }; 00571 00572 static HRESULT VideoRendererImpl_Change(IBaseFilter *iface) 00573 { 00574 TRACE("(%p)->()\n", iface); 00575 return S_OK; 00576 } 00577 00578 HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) 00579 { 00580 HRESULT hr; 00581 PIN_INFO piInput; 00582 VideoRendererImpl * pVideoRenderer; 00583 00584 TRACE("(%p, %p)\n", pUnkOuter, ppv); 00585 00586 *ppv = NULL; 00587 00588 pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl)); 00589 pVideoRenderer->pUnkOuter = pUnkOuter; 00590 pVideoRenderer->bUnkOuterValid = FALSE; 00591 pVideoRenderer->bAggregatable = FALSE; 00592 pVideoRenderer->IInner_vtbl = &IInner_VTable; 00593 00594 pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl; 00595 pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable; 00596 pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable; 00597 00598 pVideoRenderer->refCount = 1; 00599 InitializeCriticalSection(&pVideoRenderer->csFilter); 00600 pVideoRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"); 00601 pVideoRenderer->state = State_Stopped; 00602 pVideoRenderer->pClock = NULL; 00603 pVideoRenderer->init = 0; 00604 pVideoRenderer->AutoShow = 1; 00605 pVideoRenderer->rtLastStop = -1; 00606 ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO)); 00607 ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT)); 00608 ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT)); 00609 ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT)); 00610 pVideoRenderer->hWndMsgDrain = NULL; 00611 00612 /* construct input pin */ 00613 piInput.dir = PINDIR_INPUT; 00614 piInput.pFilter = (IBaseFilter *)pVideoRenderer; 00615 lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); 00616 00617 hr = InputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, NULL, &pVideoRenderer->csFilter, NULL, (IPin **)&pVideoRenderer->pInputPin); 00618 00619 if (SUCCEEDED(hr)) 00620 { 00621 MediaSeekingImpl_Init((IBaseFilter*)pVideoRenderer, VideoRendererImpl_Change, VideoRendererImpl_Change, VideoRendererImpl_Change, &pVideoRenderer->mediaSeeking, &pVideoRenderer->csFilter); 00622 pVideoRenderer->mediaSeeking.lpVtbl = &VideoRendererImpl_Seeking_Vtbl; 00623 00624 pVideoRenderer->sample_held = NULL; 00625 *ppv = pVideoRenderer; 00626 } 00627 else 00628 { 00629 pVideoRenderer->csFilter.DebugInfo->Spare[0] = 0; 00630 DeleteCriticalSection(&pVideoRenderer->csFilter); 00631 CoTaskMemFree(pVideoRenderer); 00632 } 00633 00634 if (!CreateRenderingSubsystem(pVideoRenderer)) 00635 return E_FAIL; 00636 00637 pVideoRenderer->blocked = CreateEventW(NULL, FALSE, FALSE, NULL); 00638 if (!pVideoRenderer->blocked) 00639 { 00640 hr = HRESULT_FROM_WIN32(GetLastError()); 00641 IUnknown_Release((IUnknown *)pVideoRenderer); 00642 } 00643 00644 return hr; 00645 } 00646 00647 HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv) 00648 { 00649 /* TODO: Attempt to use the VMR-7 renderer instead when possible */ 00650 return VideoRenderer_create(pUnkOuter, ppv); 00651 } 00652 00653 static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) 00654 { 00655 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); 00656 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); 00657 00658 if (This->bAggregatable) 00659 This->bUnkOuterValid = TRUE; 00660 00661 *ppv = NULL; 00662 00663 if (IsEqualIID(riid, &IID_IUnknown)) 00664 *ppv = &This->IInner_vtbl; 00665 else if (IsEqualIID(riid, &IID_IPersist)) 00666 *ppv = This; 00667 else if (IsEqualIID(riid, &IID_IMediaFilter)) 00668 *ppv = This; 00669 else if (IsEqualIID(riid, &IID_IBaseFilter)) 00670 *ppv = This; 00671 else if (IsEqualIID(riid, &IID_IBasicVideo)) 00672 *ppv = &This->IBasicVideo_vtbl; 00673 else if (IsEqualIID(riid, &IID_IVideoWindow)) 00674 *ppv = &This->IVideoWindow_vtbl; 00675 else if (IsEqualIID(riid, &IID_IMediaSeeking)) 00676 *ppv = &This->mediaSeeking; 00677 00678 if (*ppv) 00679 { 00680 IUnknown_AddRef((IUnknown *)(*ppv)); 00681 return S_OK; 00682 } 00683 00684 if (!IsEqualIID(riid, &IID_IPin)) 00685 FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); 00686 00687 return E_NOINTERFACE; 00688 } 00689 00690 static ULONG WINAPI VideoRendererInner_AddRef(IUnknown * iface) 00691 { 00692 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); 00693 ULONG refCount = InterlockedIncrement(&This->refCount); 00694 00695 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); 00696 00697 return refCount; 00698 } 00699 00700 static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface) 00701 { 00702 ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); 00703 ULONG refCount = InterlockedDecrement(&This->refCount); 00704 00705 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); 00706 00707 if (!refCount) 00708 { 00709 IPin *pConnectedTo; 00710 00711 DestroyWindow(This->hWnd); 00712 PostThreadMessageA(This->ThreadID, WM_QUIT, 0, 0); 00713 WaitForSingleObject(This->hThread, INFINITE); 00714 CloseHandle(This->hThread); 00715 CloseHandle(This->hEvent); 00716 00717 if (This->pClock) 00718 IReferenceClock_Release(This->pClock); 00719 00720 if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo))) 00721 { 00722 IPin_Disconnect(pConnectedTo); 00723 IPin_Release(pConnectedTo); 00724 } 00725 IPin_Disconnect((IPin *)This->pInputPin); 00726 00727 IPin_Release((IPin *)This->pInputPin); 00728 00729 This->lpVtbl = NULL; 00730 00731 This->csFilter.DebugInfo->Spare[0] = 0; 00732 DeleteCriticalSection(&This->csFilter); 00733 00734 TRACE("Destroying Video Renderer\n"); 00735 CoTaskMemFree(This); 00736 00737 return 0; 00738 } 00739 else 00740 return refCount; 00741 } 00742 00743 static const IUnknownVtbl IInner_VTable = 00744 { 00745 VideoRendererInner_QueryInterface, 00746 VideoRendererInner_AddRef, 00747 VideoRendererInner_Release 00748 }; 00749 00750 static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) 00751 { 00752 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00753 00754 if (This->bAggregatable) 00755 This->bUnkOuterValid = TRUE; 00756 00757 if (This->pUnkOuter) 00758 { 00759 if (This->bAggregatable) 00760 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); 00761 00762 if (IsEqualIID(riid, &IID_IUnknown)) 00763 { 00764 HRESULT hr; 00765 00766 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); 00767 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); 00768 IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); 00769 This->bAggregatable = TRUE; 00770 return hr; 00771 } 00772 00773 *ppv = NULL; 00774 return E_NOINTERFACE; 00775 } 00776 00777 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); 00778 } 00779 00780 static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface) 00781 { 00782 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00783 00784 if (This->pUnkOuter && This->bUnkOuterValid) 00785 return IUnknown_AddRef(This->pUnkOuter); 00786 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); 00787 } 00788 00789 static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface) 00790 { 00791 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00792 00793 if (This->pUnkOuter && This->bUnkOuterValid) 00794 return IUnknown_Release(This->pUnkOuter); 00795 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); 00796 } 00797 00800 static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid) 00801 { 00802 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00803 00804 TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); 00805 00806 *pClsid = CLSID_VideoRenderer; 00807 00808 return S_OK; 00809 } 00810 00813 static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface) 00814 { 00815 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00816 00817 TRACE("(%p/%p)->()\n", This, iface); 00818 00819 EnterCriticalSection(&This->csFilter); 00820 { 00821 This->state = State_Stopped; 00822 SetEvent(This->hEvent); 00823 SetEvent(This->blocked); 00824 } 00825 LeaveCriticalSection(&This->csFilter); 00826 00827 return S_OK; 00828 } 00829 00830 static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface) 00831 { 00832 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00833 00834 TRACE("(%p/%p)->()\n", This, iface); 00835 00836 EnterCriticalSection(&This->csFilter); 00837 if (This->state != State_Paused) 00838 { 00839 if (This->state == State_Stopped) 00840 { 00841 This->pInputPin->end_of_stream = 0; 00842 ResetEvent(This->hEvent); 00843 } 00844 00845 This->state = State_Paused; 00846 ResetEvent(This->blocked); 00847 } 00848 LeaveCriticalSection(&This->csFilter); 00849 00850 return S_OK; 00851 } 00852 00853 static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart) 00854 { 00855 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00856 00857 TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); 00858 00859 EnterCriticalSection(&This->csFilter); 00860 if (This->state != State_Running) 00861 { 00862 if (This->state == State_Stopped) 00863 { 00864 This->pInputPin->end_of_stream = 0; 00865 ResetEvent(This->hEvent); 00866 } 00867 SetEvent(This->blocked); 00868 00869 This->rtStreamStart = tStart; 00870 This->state = State_Running; 00871 } 00872 LeaveCriticalSection(&This->csFilter); 00873 00874 return S_OK; 00875 } 00876 00877 static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) 00878 { 00879 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00880 HRESULT hr; 00881 00882 TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); 00883 00884 if (WaitForSingleObject(This->hEvent, dwMilliSecsTimeout) == WAIT_TIMEOUT) 00885 hr = VFW_S_STATE_INTERMEDIATE; 00886 else 00887 hr = S_OK; 00888 00889 EnterCriticalSection(&This->csFilter); 00890 { 00891 *pState = This->state; 00892 } 00893 LeaveCriticalSection(&This->csFilter); 00894 00895 return hr; 00896 } 00897 00898 static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) 00899 { 00900 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00901 00902 TRACE("(%p/%p)->(%p)\n", This, iface, pClock); 00903 00904 EnterCriticalSection(&This->csFilter); 00905 { 00906 if (This->pClock) 00907 IReferenceClock_Release(This->pClock); 00908 This->pClock = pClock; 00909 if (This->pClock) 00910 IReferenceClock_AddRef(This->pClock); 00911 } 00912 LeaveCriticalSection(&This->csFilter); 00913 00914 return S_OK; 00915 } 00916 00917 static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) 00918 { 00919 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00920 00921 TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); 00922 00923 EnterCriticalSection(&This->csFilter); 00924 { 00925 *ppClock = This->pClock; 00926 if (This->pClock) 00927 IReferenceClock_AddRef(This->pClock); 00928 } 00929 LeaveCriticalSection(&This->csFilter); 00930 00931 return S_OK; 00932 } 00933 00936 static HRESULT VideoRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) 00937 { 00938 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00939 00940 /* Our pins are static, not changing so setting static tick count is ok */ 00941 *lastsynctick = 0; 00942 00943 if (pos >= 1) 00944 return S_FALSE; 00945 00946 *pin = (IPin *)This->pInputPin; 00947 IPin_AddRef(*pin); 00948 return S_OK; 00949 } 00950 00951 static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) 00952 { 00953 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00954 00955 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); 00956 00957 return IEnumPinsImpl_Construct(ppEnum, VideoRenderer_GetPin, iface); 00958 } 00959 00960 static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) 00961 { 00962 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00963 00964 FIXME("(%p/%p)->(%p,%p): stub !!!\n", This, iface, debugstr_w(Id), ppPin); 00965 00966 /* FIXME: critical section */ 00967 00968 return E_NOTIMPL; 00969 } 00970 00971 static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) 00972 { 00973 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00974 00975 TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); 00976 00977 strcpyW(pInfo->achName, This->filterInfo.achName); 00978 pInfo->pGraph = This->filterInfo.pGraph; 00979 00980 if (pInfo->pGraph) 00981 IFilterGraph_AddRef(pInfo->pGraph); 00982 00983 return S_OK; 00984 } 00985 00986 static HRESULT WINAPI VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) 00987 { 00988 VideoRendererImpl *This = (VideoRendererImpl *)iface; 00989 00990 TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); 00991 00992 EnterCriticalSection(&This->csFilter); 00993 { 00994 if (pName) 00995 strcpyW(This->filterInfo.achName, pName); 00996 else 00997 *This->filterInfo.achName = '\0'; 00998 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ 00999 } 01000 LeaveCriticalSection(&This->csFilter); 01001 01002 return S_OK; 01003 } 01004 01005 static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) 01006 { 01007 VideoRendererImpl *This = (VideoRendererImpl *)iface; 01008 TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); 01009 return E_NOTIMPL; 01010 } 01011 01012 static const IBaseFilterVtbl VideoRenderer_Vtbl = 01013 { 01014 VideoRenderer_QueryInterface, 01015 VideoRenderer_AddRef, 01016 VideoRenderer_Release, 01017 VideoRenderer_GetClassID, 01018 VideoRenderer_Stop, 01019 VideoRenderer_Pause, 01020 VideoRenderer_Run, 01021 VideoRenderer_GetState, 01022 VideoRenderer_SetSyncSource, 01023 VideoRenderer_GetSyncSource, 01024 VideoRenderer_EnumPins, 01025 VideoRenderer_FindPin, 01026 VideoRenderer_QueryFilterInfo, 01027 VideoRenderer_JoinFilterGraph, 01028 VideoRenderer_QueryVendorInfo 01029 }; 01030 01031 static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface) 01032 { 01033 InputPin* This = (InputPin*)iface; 01034 IMediaEventSink* pEventSink; 01035 HRESULT hr; 01036 01037 TRACE("(%p/%p)->()\n", This, iface); 01038 01039 hr = IFilterGraph_QueryInterface(((VideoRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); 01040 if (SUCCEEDED(hr)) 01041 { 01042 hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0); 01043 IMediaEventSink_Release(pEventSink); 01044 } 01045 01046 return hr; 01047 } 01048 01049 static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface) 01050 { 01051 InputPin* This = (InputPin*)iface; 01052 VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter; 01053 HRESULT hr; 01054 01055 TRACE("(%p/%p)->()\n", This, iface); 01056 01057 EnterCriticalSection(This->pin.pCritSec); 01058 if (pVideoRenderer->state == State_Paused) 01059 SetEvent(pVideoRenderer->blocked); 01060 01061 hr = InputPin_BeginFlush(iface); 01062 LeaveCriticalSection(This->pin.pCritSec); 01063 01064 return hr; 01065 } 01066 01067 static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface) 01068 { 01069 InputPin* This = (InputPin*)iface; 01070 VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter; 01071 HRESULT hr; 01072 01073 TRACE("(%p/%p)->()\n", This, iface); 01074 01075 EnterCriticalSection(This->pin.pCritSec); 01076 if (pVideoRenderer->state == State_Paused) 01077 ResetEvent(pVideoRenderer->blocked); 01078 01079 hr = InputPin_EndFlush(iface); 01080 LeaveCriticalSection(This->pin.pCritSec); 01081 01082 return hr; 01083 } 01084 01085 static const IPinVtbl VideoRenderer_InputPin_Vtbl = 01086 { 01087 InputPin_QueryInterface, 01088 IPinImpl_AddRef, 01089 InputPin_Release, 01090 InputPin_Connect, 01091 InputPin_ReceiveConnection, 01092 IPinImpl_Disconnect, 01093 IPinImpl_ConnectedTo, 01094 IPinImpl_ConnectionMediaType, 01095 IPinImpl_QueryPinInfo, 01096 IPinImpl_QueryDirection, 01097 IPinImpl_QueryId, 01098 IPinImpl_QueryAccept, 01099 IPinImpl_EnumMediaTypes, 01100 IPinImpl_QueryInternalConnections, 01101 VideoRenderer_InputPin_EndOfStream, 01102 VideoRenderer_InputPin_BeginFlush, 01103 VideoRenderer_InputPin_EndFlush, 01104 InputPin_NewSegment 01105 }; 01106 01107 /*** IUnknown methods ***/ 01108 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, 01109 REFIID riid, 01110 LPVOID*ppvObj) { 01111 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01112 01113 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); 01114 01115 return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj); 01116 } 01117 01118 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) { 01119 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01120 01121 TRACE("(%p/%p)->()\n", This, iface); 01122 01123 return VideoRenderer_AddRef((IBaseFilter*)This); 01124 } 01125 01126 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) { 01127 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01128 01129 TRACE("(%p/%p)->()\n", This, iface); 01130 01131 return VideoRenderer_Release((IBaseFilter*)This); 01132 } 01133 01134 /*** IDispatch methods ***/ 01135 static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface, 01136 UINT*pctinfo) { 01137 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01138 01139 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); 01140 01141 return S_OK; 01142 } 01143 01144 static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface, 01145 UINT iTInfo, 01146 LCID lcid, 01147 ITypeInfo**ppTInfo) { 01148 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01149 01150 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); 01151 01152 return S_OK; 01153 } 01154 01155 static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface, 01156 REFIID riid, 01157 LPOLESTR*rgszNames, 01158 UINT cNames, 01159 LCID lcid, 01160 DISPID*rgDispId) { 01161 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01162 01163 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); 01164 01165 return S_OK; 01166 } 01167 01168 static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface, 01169 DISPID dispIdMember, 01170 REFIID riid, 01171 LCID lcid, 01172 WORD wFlags, 01173 DISPPARAMS*pDispParams, 01174 VARIANT*pVarResult, 01175 EXCEPINFO*pExepInfo, 01176 UINT*puArgErr) { 01177 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01178 01179 FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); 01180 01181 return S_OK; 01182 } 01183 01184 /*** IBasicVideo methods ***/ 01185 static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface, 01186 REFTIME *pAvgTimePerFrame) { 01187 AM_MEDIA_TYPE *pmt; 01188 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01189 01190 if (!This->pInputPin->pin.pConnectedTo) 01191 return VFW_E_NOT_CONNECTED; 01192 01193 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); 01194 01195 pmt = &This->pInputPin->pin.mtCurrent; 01196 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { 01197 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat; 01198 *pAvgTimePerFrame = vih->AvgTimePerFrame; 01199 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { 01200 VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat; 01201 *pAvgTimePerFrame = vih->AvgTimePerFrame; 01202 } else { 01203 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); 01204 *pAvgTimePerFrame = 0; 01205 } 01206 return S_OK; 01207 } 01208 01209 static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface, 01210 LONG *pBitRate) { 01211 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01212 01213 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate); 01214 01215 return S_OK; 01216 } 01217 01218 static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface, 01219 LONG *pBitErrorRate) { 01220 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01221 01222 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate); 01223 01224 return S_OK; 01225 } 01226 01227 static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface, 01228 LONG *pVideoWidth) { 01229 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01230 01231 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); 01232 01233 *pVideoWidth = This->VideoWidth; 01234 01235 return S_OK; 01236 } 01237 01238 static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface, 01239 LONG *pVideoHeight) { 01240 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01241 01242 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); 01243 01244 *pVideoHeight = This->VideoHeight; 01245 01246 return S_OK; 01247 } 01248 01249 static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface, 01250 LONG SourceLeft) { 01251 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01252 01253 TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft); 01254 01255 This->SourceRect.left = SourceLeft; 01256 01257 return S_OK; 01258 } 01259 01260 static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface, 01261 LONG *pSourceLeft) { 01262 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01263 01264 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); 01265 01266 *pSourceLeft = This->SourceRect.left; 01267 01268 return S_OK; 01269 } 01270 01271 static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface, 01272 LONG SourceWidth) { 01273 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01274 01275 TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth); 01276 01277 This->SourceRect.right = This->SourceRect.left + SourceWidth; 01278 01279 return S_OK; 01280 } 01281 01282 static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface, 01283 LONG *pSourceWidth) { 01284 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01285 01286 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); 01287 01288 *pSourceWidth = This->SourceRect.right - This->SourceRect.left; 01289 01290 return S_OK; 01291 } 01292 01293 static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface, 01294 LONG SourceTop) { 01295 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01296 01297 TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop); 01298 01299 This->SourceRect.top = SourceTop; 01300 01301 return S_OK; 01302 } 01303 01304 static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface, 01305 LONG *pSourceTop) { 01306 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01307 01308 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); 01309 01310 *pSourceTop = This->SourceRect.top; 01311 01312 return S_OK; 01313 } 01314 01315 static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface, 01316 LONG SourceHeight) { 01317 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01318 01319 TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight); 01320 01321 This->SourceRect.bottom = This->SourceRect.top + SourceHeight; 01322 01323 return S_OK; 01324 } 01325 01326 static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface, 01327 LONG *pSourceHeight) { 01328 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01329 01330 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); 01331 01332 *pSourceHeight = This->SourceRect.bottom - This->SourceRect.top; 01333 01334 return S_OK; 01335 } 01336 01337 static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface, 01338 LONG DestinationLeft) { 01339 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01340 01341 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft); 01342 01343 This->DestRect.left = DestinationLeft; 01344 01345 return S_OK; 01346 } 01347 01348 static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface, 01349 LONG *pDestinationLeft) { 01350 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01351 01352 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); 01353 01354 *pDestinationLeft = This->DestRect.left; 01355 01356 return S_OK; 01357 } 01358 01359 static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface, 01360 LONG DestinationWidth) { 01361 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01362 01363 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth); 01364 01365 This->DestRect.right = This->DestRect.left + DestinationWidth; 01366 01367 return S_OK; 01368 } 01369 01370 static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface, 01371 LONG *pDestinationWidth) { 01372 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01373 01374 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); 01375 01376 *pDestinationWidth = This->DestRect.right - This->DestRect.left; 01377 01378 return S_OK; 01379 } 01380 01381 static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface, 01382 LONG DestinationTop) { 01383 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01384 01385 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop); 01386 01387 This->DestRect.top = DestinationTop; 01388 01389 return S_OK; 01390 } 01391 01392 static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface, 01393 LONG *pDestinationTop) { 01394 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01395 01396 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); 01397 01398 *pDestinationTop = This->DestRect.top; 01399 01400 return S_OK; 01401 } 01402 01403 static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface, 01404 LONG DestinationHeight) { 01405 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01406 01407 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight); 01408 01409 This->DestRect.right = This->DestRect.left + DestinationHeight; 01410 01411 return S_OK; 01412 } 01413 01414 static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface, 01415 LONG *pDestinationHeight) { 01416 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01417 01418 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); 01419 01420 *pDestinationHeight = This->DestRect.right - This->DestRect.left; 01421 01422 return S_OK; 01423 } 01424 01425 static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface, 01426 LONG Left, 01427 LONG Top, 01428 LONG Width, 01429 LONG Height) { 01430 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01431 01432 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); 01433 01434 This->SourceRect.left = Left; 01435 This->SourceRect.top = Top; 01436 This->SourceRect.right = Left + Width; 01437 This->SourceRect.bottom = Top + Height; 01438 01439 return S_OK; 01440 } 01441 01442 static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface, 01443 LONG *pLeft, 01444 LONG *pTop, 01445 LONG *pWidth, 01446 LONG *pHeight) { 01447 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01448 01449 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); 01450 01451 *pLeft = This->SourceRect.left; 01452 *pTop = This->SourceRect.top; 01453 *pWidth = This->SourceRect.right - This->SourceRect.left; 01454 *pHeight = This->SourceRect.bottom - This->SourceRect.top; 01455 01456 return S_OK; 01457 } 01458 01459 static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) { 01460 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01461 01462 TRACE("(%p/%p)->()\n", This, iface); 01463 01464 This->SourceRect.left = 0; 01465 This->SourceRect.top = 0; 01466 This->SourceRect.right = This->VideoWidth; 01467 This->SourceRect.bottom = This->VideoHeight; 01468 01469 return S_OK; 01470 } 01471 01472 static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface, 01473 LONG Left, 01474 LONG Top, 01475 LONG Width, 01476 LONG Height) { 01477 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01478 01479 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); 01480 01481 This->DestRect.left = Left; 01482 This->DestRect.top = Top; 01483 This->DestRect.right = Left + Width; 01484 This->DestRect.bottom = Top + Height; 01485 01486 return S_OK; 01487 } 01488 01489 static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface, 01490 LONG *pLeft, 01491 LONG *pTop, 01492 LONG *pWidth, 01493 LONG *pHeight) { 01494 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01495 01496 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); 01497 01498 *pLeft = This->DestRect.left; 01499 *pTop = This->DestRect.top; 01500 *pWidth = This->DestRect.right - This->DestRect.left; 01501 *pHeight = This->DestRect.bottom - This->DestRect.top; 01502 01503 return S_OK; 01504 } 01505 01506 static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) { 01507 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01508 RECT rect; 01509 01510 TRACE("(%p/%p)->()\n", This, iface); 01511 01512 if (!GetClientRect(This->hWnd, &rect)) 01513 return E_FAIL; 01514 01515 This->SourceRect.left = 0; 01516 This->SourceRect.top = 0; 01517 This->SourceRect.right = rect.right; 01518 This->SourceRect.bottom = rect.bottom; 01519 01520 return S_OK; 01521 } 01522 01523 static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface, 01524 LONG *pWidth, 01525 LONG *pHeight) { 01526 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01527 01528 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); 01529 01530 *pWidth = This->VideoWidth; 01531 *pHeight = This->VideoHeight; 01532 01533 return S_OK; 01534 } 01535 01536 static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface, 01537 LONG StartIndex, 01538 LONG Entries, 01539 LONG *pRetrieved, 01540 LONG *pPalette) { 01541 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01542 01543 FIXME("(%p/%p)->(%d, %d, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); 01544 01545 return S_OK; 01546 } 01547 01548 static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface, 01549 LONG *pBufferSize, 01550 LONG *pDIBImage) { 01551 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01552 BITMAPINFOHEADER *bmiHeader; 01553 LONG needed_size; 01554 AM_MEDIA_TYPE *amt = &This->pInputPin->pin.mtCurrent; 01555 char *ptr; 01556 01557 FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage); 01558 01559 EnterCriticalSection(&This->csFilter); 01560 01561 if (!This->sample_held) 01562 { 01563 LeaveCriticalSection(&This->csFilter); 01564 return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); 01565 } 01566 01567 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) 01568 { 01569 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; 01570 } 01571 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) 01572 { 01573 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; 01574 } 01575 else 01576 { 01577 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); 01578 LeaveCriticalSection(&This->csFilter); 01579 return VFW_E_RUNTIME_ERROR; 01580 } 01581 01582 needed_size = bmiHeader->biSize; 01583 needed_size += IMediaSample_GetActualDataLength(This->sample_held); 01584 01585 if (!pDIBImage) 01586 { 01587 *pBufferSize = needed_size; 01588 LeaveCriticalSection(&This->csFilter); 01589 return S_OK; 01590 } 01591 01592 if (needed_size < *pBufferSize) 01593 { 01594 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize); 01595 LeaveCriticalSection(&This->csFilter); 01596 return E_FAIL; 01597 } 01598 *pBufferSize = needed_size; 01599 01600 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); 01601 IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr); 01602 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held)); 01603 01604 LeaveCriticalSection(&This->csFilter); 01605 01606 return S_OK; 01607 } 01608 01609 static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) { 01610 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01611 01612 FIXME("(%p/%p)->(): stub !!!\n", This, iface); 01613 01614 return S_OK; 01615 } 01616 01617 static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) { 01618 ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); 01619 01620 FIXME("(%p/%p)->(): stub !!!\n", This, iface); 01621 01622 return S_OK; 01623 } 01624 01625 01626 static const IBasicVideoVtbl IBasicVideo_VTable = 01627 { 01628 Basicvideo_QueryInterface, 01629 Basicvideo_AddRef, 01630 Basicvideo_Release, 01631 Basicvideo_GetTypeInfoCount, 01632 Basicvideo_GetTypeInfo, 01633 Basicvideo_GetIDsOfNames, 01634 Basicvideo_Invoke, 01635 Basicvideo_get_AvgTimePerFrame, 01636 Basicvideo_get_BitRate, 01637 Basicvideo_get_BitErrorRate, 01638 Basicvideo_get_VideoWidth, 01639 Basicvideo_get_VideoHeight, 01640 Basicvideo_put_SourceLeft, 01641 Basicvideo_get_SourceLeft, 01642 Basicvideo_put_SourceWidth, 01643 Basicvideo_get_SourceWidth, 01644 Basicvideo_put_SourceTop, 01645 Basicvideo_get_SourceTop, 01646 Basicvideo_put_SourceHeight, 01647 Basicvideo_get_SourceHeight, 01648 Basicvideo_put_DestinationLeft, 01649 Basicvideo_get_DestinationLeft, 01650 Basicvideo_put_DestinationWidth, 01651 Basicvideo_get_DestinationWidth, 01652 Basicvideo_put_DestinationTop, 01653 Basicvideo_get_DestinationTop, 01654 Basicvideo_put_DestinationHeight, 01655 Basicvideo_get_DestinationHeight, 01656 Basicvideo_SetSourcePosition, 01657 Basicvideo_GetSourcePosition, 01658 Basicvideo_SetDefaultSourcePosition, 01659 Basicvideo_SetDestinationPosition, 01660 Basicvideo_GetDestinationPosition, 01661 Basicvideo_SetDefaultDestinationPosition, 01662 Basicvideo_GetVideoSize, 01663 Basicvideo_GetVideoPaletteEntries, 01664 Basicvideo_GetCurrentImage, 01665 Basicvideo_IsUsingDefaultSource, 01666 Basicvideo_IsUsingDefaultDestination 01667 }; 01668 01669 01670 /*** IUnknown methods ***/ 01671 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, 01672 REFIID riid, 01673 LPVOID*ppvObj) { 01674 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01675 01676 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); 01677 01678 return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj); 01679 } 01680 01681 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) { 01682 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01683 01684 TRACE("(%p/%p)->()\n", This, iface); 01685 01686 return VideoRenderer_AddRef((IBaseFilter*)This); 01687 } 01688 01689 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) { 01690 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01691 01692 TRACE("(%p/%p)->()\n", This, iface); 01693 01694 return VideoRenderer_Release((IBaseFilter*)This); 01695 } 01696 01697 /*** IDispatch methods ***/ 01698 static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface, 01699 UINT*pctinfo) { 01700 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01701 01702 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); 01703 01704 return S_OK; 01705 } 01706 01707 static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface, 01708 UINT iTInfo, 01709 LCID lcid, 01710 ITypeInfo**ppTInfo) { 01711 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01712 01713 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); 01714 01715 return S_OK; 01716 } 01717 01718 static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface, 01719 REFIID riid, 01720 LPOLESTR*rgszNames, 01721 UINT cNames, 01722 LCID lcid, 01723 DISPID*rgDispId) { 01724 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01725 01726 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); 01727 01728 return S_OK; 01729 } 01730 01731 static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface, 01732 DISPID dispIdMember, 01733 REFIID riid, 01734 LCID lcid, 01735 WORD wFlags, 01736 DISPPARAMS*pDispParams, 01737 VARIANT*pVarResult, 01738 EXCEPINFO*pExepInfo, 01739 UINT*puArgErr) { 01740 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01741 01742 FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); 01743 01744 return S_OK; 01745 } 01746 01747 /*** IVideoWindow methods ***/ 01748 static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface, 01749 BSTR strCaption) { 01750 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01751 01752 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption); 01753 01754 if (!SetWindowTextW(This->hWnd, strCaption)) 01755 return E_FAIL; 01756 01757 return S_OK; 01758 } 01759 01760 static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface, 01761 BSTR *strCaption) { 01762 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01763 01764 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption); 01765 01766 GetWindowTextW(This->hWnd, (LPWSTR)strCaption, 100); 01767 01768 return S_OK; 01769 } 01770 01771 static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface, 01772 LONG WindowStyle) { 01773 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01774 LONG old; 01775 01776 old = GetWindowLongA(This->hWnd, GWL_STYLE); 01777 01778 TRACE("(%p/%p)->(%x -> %x)\n", This, iface, old, WindowStyle); 01779 01780 if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) 01781 return E_INVALIDARG; 01782 01783 SetWindowLongA(This->hWnd, GWL_STYLE, WindowStyle); 01784 01785 return S_OK; 01786 } 01787 01788 static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface, 01789 LONG *WindowStyle) { 01790 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01791 01792 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle); 01793 01794 *WindowStyle = GetWindowLongA(This->hWnd, GWL_STYLE); 01795 01796 return S_OK; 01797 } 01798 01799 static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface, 01800 LONG WindowStyleEx) { 01801 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01802 01803 TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); 01804 01805 if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx)) 01806 return E_FAIL; 01807 01808 return S_OK; 01809 } 01810 01811 static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface, 01812 LONG *WindowStyleEx) { 01813 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01814 01815 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx); 01816 01817 *WindowStyleEx = GetWindowLongA(This->hWnd, GWL_EXSTYLE); 01818 01819 return S_OK; 01820 } 01821 01822 static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface, 01823 LONG AutoShow) { 01824 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01825 01826 TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); 01827 01828 This->AutoShow = AutoShow; 01829 01830 return S_OK; 01831 } 01832 01833 static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface, 01834 LONG *AutoShow) { 01835 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01836 01837 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow); 01838 01839 *AutoShow = This->AutoShow; 01840 01841 return S_OK; 01842 } 01843 01844 static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface, 01845 LONG WindowState) { 01846 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01847 01848 TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); 01849 ShowWindow(This->hWnd, WindowState); 01850 return S_OK; 01851 } 01852 01853 static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface, 01854 LONG *WindowState) { 01855 WINDOWPLACEMENT place; 01856 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01857 01858 place.length = sizeof(place); 01859 GetWindowPlacement(This->hWnd, &place); 01860 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); 01861 *WindowState = place.showCmd; 01862 01863 return S_OK; 01864 } 01865 01866 static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface, 01867 LONG BackgroundPalette) { 01868 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01869 01870 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, BackgroundPalette); 01871 01872 return S_OK; 01873 } 01874 01875 static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface, 01876 LONG *pBackgroundPalette) { 01877 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01878 01879 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette); 01880 01881 return S_OK; 01882 } 01883 01884 static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface, 01885 LONG Visible) { 01886 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01887 01888 TRACE("(%p/%p)->(%d)\n", This, iface, Visible); 01889 01890 ShowWindow(This->hWnd, Visible ? SW_SHOW : SW_HIDE); 01891 01892 return S_OK; 01893 } 01894 01895 static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface, 01896 LONG *pVisible) { 01897 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01898 01899 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible); 01900 01901 *pVisible = IsWindowVisible(This->hWnd); 01902 01903 return S_OK; 01904 } 01905 01906 static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface, 01907 LONG Left) { 01908 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01909 01910 TRACE("(%p/%p)->(%d)\n", This, iface, Left); 01911 01912 if (!SetWindowPos(This->hWnd, NULL, Left, This->WindowPos.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) 01913 return E_FAIL; 01914 01915 This->WindowPos.left = Left; 01916 01917 return S_OK; 01918 } 01919 01920 static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface, 01921 LONG *pLeft) { 01922 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01923 01924 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft); 01925 01926 *pLeft = This->WindowPos.left; 01927 01928 return S_OK; 01929 } 01930 01931 static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface, 01932 LONG Width) { 01933 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01934 01935 TRACE("(%p/%p)->(%d)\n", This, iface, Width); 01936 01937 if (!SetWindowPos(This->hWnd, NULL, 0, 0, Width, This->WindowPos.bottom-This->WindowPos.top, SWP_NOZORDER|SWP_NOMOVE)) 01938 return E_FAIL; 01939 01940 This->WindowPos.right = This->WindowPos.left + Width; 01941 01942 return S_OK; 01943 } 01944 01945 static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface, 01946 LONG *pWidth) { 01947 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01948 01949 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth); 01950 01951 *pWidth = This->WindowPos.right - This->WindowPos.left; 01952 01953 return S_OK; 01954 } 01955 01956 static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface, 01957 LONG Top) { 01958 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01959 01960 TRACE("(%p/%p)->(%d)\n", This, iface, Top); 01961 01962 if (!SetWindowPos(This->hWnd, NULL, This->WindowPos.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) 01963 return E_FAIL; 01964 01965 This->WindowPos.top = Top; 01966 01967 return S_OK; 01968 } 01969 01970 static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface, 01971 LONG *pTop) { 01972 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01973 01974 TRACE("(%p/%p)->(%p)\n", This, iface, pTop); 01975 01976 *pTop = This->WindowPos.top; 01977 01978 return S_OK; 01979 } 01980 01981 static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface, 01982 LONG Height) { 01983 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01984 01985 TRACE("(%p/%p)->(%d)\n", This, iface, Height); 01986 01987 if (!SetWindowPos(This->hWnd, NULL, 0, 0, This->WindowPos.right-This->WindowPos.left, Height, SWP_NOZORDER|SWP_NOMOVE)) 01988 return E_FAIL; 01989 01990 This->WindowPos.bottom = This->WindowPos.top + Height; 01991 01992 return S_OK; 01993 } 01994 01995 static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface, 01996 LONG *pHeight) { 01997 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 01998 01999 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight); 02000 02001 *pHeight = This->WindowPos.bottom - This->WindowPos.top; 02002 02003 return S_OK; 02004 } 02005 02006 static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface, 02007 OAHWND Owner) { 02008 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02009 02010 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); 02011 02012 SetParent(This->hWnd, (HWND)Owner); 02013 02014 return S_OK; 02015 } 02016 02017 static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface, 02018 OAHWND *Owner) { 02019 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02020 02021 TRACE("(%p/%p)->(%p)\n", This, iface, Owner); 02022 02023 *(HWND*)Owner = GetParent(This->hWnd); 02024 02025 return S_OK; 02026 } 02027 02028 static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface, 02029 OAHWND Drain) { 02030 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02031 02032 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain); 02033 02034 This->hWndMsgDrain = (HWND)Drain; 02035 02036 return S_OK; 02037 } 02038 02039 static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface, 02040 OAHWND *Drain) { 02041 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02042 02043 TRACE("(%p/%p)->(%p)\n", This, iface, Drain); 02044 02045 *Drain = (OAHWND)This->hWndMsgDrain; 02046 02047 return S_OK; 02048 } 02049 02050 static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface, 02051 LONG *Color) { 02052 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02053 02054 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color); 02055 02056 return S_OK; 02057 } 02058 02059 static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface, 02060 LONG Color) { 02061 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02062 02063 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, Color); 02064 02065 return S_OK; 02066 } 02067 02068 static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface, 02069 LONG *FullScreenMode) { 02070 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02071 02072 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode); 02073 02074 return S_OK; 02075 } 02076 02077 static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface, 02078 LONG FullScreenMode) { 02079 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02080 02081 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, FullScreenMode); 02082 02083 return S_OK; 02084 } 02085 02086 static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface, 02087 LONG Focus) { 02088 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02089 BOOL ret; 02090 IPin* pPin; 02091 HRESULT hr; 02092 02093 TRACE("(%p/%p)->(%d)\n", This, iface, Focus); 02094 02095 if ((Focus != FALSE) && (Focus != TRUE)) 02096 return E_INVALIDARG; 02097 02098 hr = IPin_ConnectedTo((IPin *)This->pInputPin, &pPin); 02099 if ((hr != S_OK) || !pPin) 02100 return VFW_E_NOT_CONNECTED; 02101 02102 if (Focus) 02103 ret = SetForegroundWindow(This->hWnd); 02104 else 02105 ret = SetWindowPos(This->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 02106 02107 if (!ret) 02108 return E_FAIL; 02109 02110 return S_OK; 02111 } 02112 02113 static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface, 02114 OAHWND hwnd, 02115 LONG uMsg, 02116 LONG_PTR wParam, 02117 LONG_PTR lParam) { 02118 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02119 02120 TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam); 02121 02122 if (!PostMessageA(This->hWnd, uMsg, wParam, lParam)) 02123 return E_FAIL; 02124 02125 return S_OK; 02126 } 02127 02128 static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface, 02129 LONG Left, 02130 LONG Top, 02131 LONG Width, 02132 LONG Height) { 02133 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02134 02135 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); 02136 02137 if (!SetWindowPos(This->hWnd, NULL, Left, Top, Width, Height, SWP_NOZORDER)) 02138 return E_FAIL; 02139 02140 This->WindowPos.left = Left; 02141 This->WindowPos.top = Top; 02142 This->WindowPos.right = Left + Width; 02143 This->WindowPos.bottom = Top + Height; 02144 02145 return S_OK; 02146 } 02147 02148 static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface, 02149 LONG *pLeft, 02150 LONG *pTop, 02151 LONG *pWidth, 02152 LONG *pHeight) { 02153 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02154 02155 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); 02156 02157 *pLeft = This->WindowPos.left; 02158 *pTop = This->WindowPos.top; 02159 *pWidth = This->WindowPos.right - This->WindowPos.left; 02160 *pHeight = This->WindowPos.bottom - This->WindowPos.top; 02161 02162 return S_OK; 02163 } 02164 02165 static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface, 02166 LONG *pWidth, 02167 LONG *pHeight) { 02168 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02169 02170 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); 02171 02172 *pWidth = This->VideoWidth; 02173 *pHeight = This->VideoHeight; 02174 02175 return S_OK; 02176 } 02177 02178 static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface, 02179 LONG *pWidth, 02180 LONG *pHeight) { 02181 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02182 02183 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); 02184 02185 *pWidth = This->VideoWidth; 02186 *pHeight = This->VideoHeight; 02187 02188 return S_OK; 02189 } 02190 02191 static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface, 02192 LONG *pLeft, 02193 LONG *pTop, 02194 LONG *pWidth, 02195 LONG *pHeight) { 02196 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02197 02198 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight); 02199 02200 return S_OK; 02201 } 02202 02203 static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface, 02204 LONG HideCursor) { 02205 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02206 02207 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, HideCursor); 02208 02209 return S_OK; 02210 } 02211 02212 static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface, 02213 LONG *CursorHidden) { 02214 ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); 02215 02216 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden); 02217 02218 return S_OK; 02219 } 02220 02221 static const IVideoWindowVtbl IVideoWindow_VTable = 02222 { 02223 Videowindow_QueryInterface, 02224 Videowindow_AddRef, 02225 Videowindow_Release, 02226 Videowindow_GetTypeInfoCount, 02227 Videowindow_GetTypeInfo, 02228 Videowindow_GetIDsOfNames, 02229 Videowindow_Invoke, 02230 Videowindow_put_Caption, 02231 Videowindow_get_Caption, 02232 Videowindow_put_WindowStyle, 02233 Videowindow_get_WindowStyle, 02234 Videowindow_put_WindowStyleEx, 02235 Videowindow_get_WindowStyleEx, 02236 Videowindow_put_AutoShow, 02237 Videowindow_get_AutoShow, 02238 Videowindow_put_WindowState, 02239 Videowindow_get_WindowState, 02240 Videowindow_put_BackgroundPalette, 02241 Videowindow_get_BackgroundPalette, 02242 Videowindow_put_Visible, 02243 Videowindow_get_Visible, 02244 Videowindow_put_Left, 02245 Videowindow_get_Left, 02246 Videowindow_put_Width, 02247 Videowindow_get_Width, 02248 Videowindow_put_Top, 02249 Videowindow_get_Top, 02250 Videowindow_put_Height, 02251 Videowindow_get_Height, 02252 Videowindow_put_Owner, 02253 Videowindow_get_Owner, 02254 Videowindow_put_MessageDrain, 02255 Videowindow_get_MessageDrain, 02256 Videowindow_get_BorderColor, 02257 Videowindow_put_BorderColor, 02258 Videowindow_get_FullScreenMode, 02259 Videowindow_put_FullScreenMode, 02260 Videowindow_SetWindowForeground, 02261 Videowindow_NotifyOwnerMessage, 02262 Videowindow_SetWindowPosition, 02263 Videowindow_GetWindowPosition, 02264 Videowindow_GetMinIdealImageSize, 02265 Videowindow_GetMaxIdealImageSize, 02266 Videowindow_GetRestorePosition, 02267 Videowindow_HideCursor, 02268 Videowindow_IsCursorHidden 02269 }; Generated on Sat May 26 2012 04:20:34 for ReactOS by
1.7.6.1
|