Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentransform.c
Go to the documentation of this file.
00001 /* 00002 * Transform Filter (Base for decoders, etc...) 00003 * 00004 * Copyright 2005 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 #include "quartz_private.h" 00024 #include "control_private.h" 00025 #include "pin.h" 00026 00027 #include "amvideo.h" 00028 #include "windef.h" 00029 #include "winbase.h" 00030 #include "dshow.h" 00031 #include "strmif.h" 00032 #include "vfw.h" 00033 00034 #include <assert.h> 00035 00036 #include "wine/unicode.h" 00037 #include "wine/debug.h" 00038 00039 #include "transform.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(quartz); 00042 00043 static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; 00044 static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0}; 00045 00046 static const IBaseFilterVtbl TransformFilter_Vtbl; 00047 static const IPinVtbl TransformFilter_InputPin_Vtbl; 00048 static const IPinVtbl TransformFilter_OutputPin_Vtbl; 00049 00050 static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) 00051 { 00052 TransformFilterImpl* This = (TransformFilterImpl *)((IPinImpl *)iface)->pinInfo.pFilter; 00053 TRACE("%p\n", iface); 00054 dump_AM_MEDIA_TYPE(pmt); 00055 00056 if (This->pFuncsTable->pfnQueryConnect) 00057 return This->pFuncsTable->pfnQueryConnect(This, pmt); 00058 /* Assume OK if there's no query method (the connection will fail if 00059 needed) */ 00060 return S_OK; 00061 } 00062 00063 00064 static HRESULT TransformFilter_Output_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) 00065 { 00066 TransformFilterImpl* pTransformFilter = iface; 00067 AM_MEDIA_TYPE* outpmt = &pTransformFilter->pmt; 00068 TRACE("%p\n", iface); 00069 00070 if (IsEqualIID(&pmt->majortype, &outpmt->majortype) 00071 && (IsEqualIID(&pmt->subtype, &outpmt->subtype) || IsEqualIID(&outpmt->subtype, &GUID_NULL))) 00072 return S_OK; 00073 return S_FALSE; 00074 } 00075 00076 00077 static inline TransformFilterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) 00078 { 00079 return (TransformFilterImpl *)((char*)iface - FIELD_OFFSET(TransformFilterImpl, mediaSeeking.lpVtbl)); 00080 } 00081 00082 static HRESULT WINAPI TransformFilter_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) 00083 { 00084 TransformFilterImpl *This = impl_from_IMediaSeeking(iface); 00085 00086 return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); 00087 } 00088 00089 static ULONG WINAPI TransformFilter_Seeking_AddRef(IMediaSeeking * iface) 00090 { 00091 TransformFilterImpl *This = impl_from_IMediaSeeking(iface); 00092 00093 return IUnknown_AddRef((IUnknown *)This); 00094 } 00095 00096 static ULONG WINAPI TransformFilter_Seeking_Release(IMediaSeeking * iface) 00097 { 00098 TransformFilterImpl *This = impl_from_IMediaSeeking(iface); 00099 00100 return IUnknown_Release((IUnknown *)This); 00101 } 00102 00103 static const IMediaSeekingVtbl TransformFilter_Seeking_Vtbl = 00104 { 00105 TransformFilter_Seeking_QueryInterface, 00106 TransformFilter_Seeking_AddRef, 00107 TransformFilter_Seeking_Release, 00108 MediaSeekingImpl_GetCapabilities, 00109 MediaSeekingImpl_CheckCapabilities, 00110 MediaSeekingImpl_IsFormatSupported, 00111 MediaSeekingImpl_QueryPreferredFormat, 00112 MediaSeekingImpl_GetTimeFormat, 00113 MediaSeekingImpl_IsUsingTimeFormat, 00114 MediaSeekingImpl_SetTimeFormat, 00115 MediaSeekingImpl_GetDuration, 00116 MediaSeekingImpl_GetStopPosition, 00117 MediaSeekingImpl_GetCurrentPosition, 00118 MediaSeekingImpl_ConvertTimeFormat, 00119 MediaSeekingImpl_SetPositions, 00120 MediaSeekingImpl_GetPositions, 00121 MediaSeekingImpl_GetAvailable, 00122 MediaSeekingImpl_SetRate, 00123 MediaSeekingImpl_GetRate, 00124 MediaSeekingImpl_GetPreroll 00125 }; 00126 00127 /* These shouldn't be implemented by default. 00128 * Usually only source filters should implement these 00129 * and even it's not needed all of the time 00130 */ 00131 static HRESULT TransformFilter_ChangeCurrent(IBaseFilter *iface) 00132 { 00133 TRACE("(%p) filter hasn't implemented current position change!\n", iface); 00134 return S_OK; 00135 } 00136 00137 static HRESULT TransformFilter_ChangeStop(IBaseFilter *iface) 00138 { 00139 TRACE("(%p) filter hasn't implemented stop position change!\n", iface); 00140 return S_OK; 00141 } 00142 00143 static HRESULT TransformFilter_ChangeRate(IBaseFilter *iface) 00144 { 00145 TRACE("(%p) filter hasn't implemented rate change!\n", iface); 00146 return S_OK; 00147 } 00148 00149 HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, const TransformFuncsTable* pFuncsTable, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate) 00150 { 00151 HRESULT hr; 00152 PIN_INFO piInput; 00153 PIN_INFO piOutput; 00154 00155 /* pTransformFilter is already allocated */ 00156 pTransformFilter->clsid = *pClsid; 00157 pTransformFilter->pFuncsTable = pFuncsTable; 00158 00159 pTransformFilter->lpVtbl = &TransformFilter_Vtbl; 00160 00161 pTransformFilter->refCount = 1; 00162 InitializeCriticalSection(&pTransformFilter->csFilter); 00163 pTransformFilter->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TransformFilterImpl.csFilter"); 00164 pTransformFilter->state = State_Stopped; 00165 pTransformFilter->pClock = NULL; 00166 ZeroMemory(&pTransformFilter->filterInfo, sizeof(FILTER_INFO)); 00167 ZeroMemory(&pTransformFilter->pmt, sizeof(pTransformFilter->pmt)); 00168 pTransformFilter->npins = 2; 00169 00170 pTransformFilter->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *)); 00171 00172 /* construct input pin */ 00173 piInput.dir = PINDIR_INPUT; 00174 piInput.pFilter = (IBaseFilter *)pTransformFilter; 00175 lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); 00176 piOutput.dir = PINDIR_OUTPUT; 00177 piOutput.pFilter = (IBaseFilter *)pTransformFilter; 00178 lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0])); 00179 00180 hr = InputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, (SAMPLEPROC_PUSH)pFuncsTable->pfnProcessSampleData, NULL, TransformFilter_Input_QueryAccept, NULL, &pTransformFilter->csFilter, NULL, &pTransformFilter->ppPins[0]); 00181 00182 if (SUCCEEDED(hr)) 00183 { 00184 ALLOCATOR_PROPERTIES props; 00185 props.cbAlign = 1; 00186 props.cbPrefix = 0; 00187 props.cbBuffer = 0; /* Will be updated at connection time */ 00188 props.cBuffers = 1; 00189 00190 ((InputPin *)pTransformFilter->ppPins[0])->pin.pUserData = pTransformFilter->ppPins[0]; 00191 00192 hr = OutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(OutputPin), &piOutput, &props, pTransformFilter, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]); 00193 00194 if (FAILED(hr)) 00195 ERR("Cannot create output pin (%x)\n", hr); 00196 else 00197 { 00198 if (!stop) 00199 stop = TransformFilter_ChangeStop; 00200 if (!current) 00201 current = TransformFilter_ChangeCurrent; 00202 if (!rate) 00203 rate = TransformFilter_ChangeRate; 00204 00205 MediaSeekingImpl_Init((IBaseFilter*)pTransformFilter, stop, current, rate, &pTransformFilter->mediaSeeking, &pTransformFilter->csFilter); 00206 pTransformFilter->mediaSeeking.lpVtbl = &TransformFilter_Seeking_Vtbl; 00207 } 00208 } 00209 else 00210 { 00211 CoTaskMemFree(pTransformFilter->ppPins); 00212 pTransformFilter->csFilter.DebugInfo->Spare[0] = 0; 00213 DeleteCriticalSection(&pTransformFilter->csFilter); 00214 CoTaskMemFree(pTransformFilter); 00215 } 00216 00217 return hr; 00218 } 00219 00220 static HRESULT WINAPI TransformFilter_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) 00221 { 00222 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00223 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); 00224 00225 *ppv = NULL; 00226 00227 if (IsEqualIID(riid, &IID_IUnknown)) 00228 *ppv = This; 00229 else if (IsEqualIID(riid, &IID_IPersist)) 00230 *ppv = This; 00231 else if (IsEqualIID(riid, &IID_IMediaFilter)) 00232 *ppv = This; 00233 else if (IsEqualIID(riid, &IID_IBaseFilter)) 00234 *ppv = This; 00235 else if (IsEqualIID(riid, &IID_IMediaSeeking)) 00236 *ppv = &This->mediaSeeking; 00237 00238 if (*ppv) 00239 { 00240 IUnknown_AddRef((IUnknown *)(*ppv)); 00241 return S_OK; 00242 } 00243 00244 if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow)) 00245 FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); 00246 00247 return E_NOINTERFACE; 00248 } 00249 00250 static ULONG WINAPI TransformFilter_AddRef(IBaseFilter * iface) 00251 { 00252 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00253 ULONG refCount = InterlockedIncrement(&This->refCount); 00254 00255 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); 00256 00257 return refCount; 00258 } 00259 00260 static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface) 00261 { 00262 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00263 ULONG refCount = InterlockedDecrement(&This->refCount); 00264 00265 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); 00266 00267 if (!refCount) 00268 { 00269 ULONG i; 00270 00271 if (This->pClock) 00272 IReferenceClock_Release(This->pClock); 00273 00274 for (i = 0; i < This->npins; i++) 00275 { 00276 IPin *pConnectedTo; 00277 00278 if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[i], &pConnectedTo))) 00279 { 00280 IPin_Disconnect(pConnectedTo); 00281 IPin_Release(pConnectedTo); 00282 } 00283 IPin_Disconnect(This->ppPins[i]); 00284 00285 IPin_Release(This->ppPins[i]); 00286 } 00287 00288 CoTaskMemFree(This->ppPins); 00289 This->lpVtbl = NULL; 00290 00291 This->csFilter.DebugInfo->Spare[0] = 0; 00292 DeleteCriticalSection(&This->csFilter); 00293 00294 TRACE("Destroying transform filter\n"); 00295 FreeMediaType(&This->pmt); 00296 CoTaskMemFree(This); 00297 00298 return 0; 00299 } 00300 else 00301 return refCount; 00302 } 00303 00306 static HRESULT WINAPI TransformFilter_GetClassID(IBaseFilter * iface, CLSID * pClsid) 00307 { 00308 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00309 00310 TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); 00311 00312 *pClsid = This->clsid; 00313 00314 return S_OK; 00315 } 00316 00319 static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface) 00320 { 00321 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00322 HRESULT hr = S_OK; 00323 00324 TRACE("(%p/%p)\n", This, iface); 00325 00326 EnterCriticalSection(&This->csFilter); 00327 { 00328 This->state = State_Stopped; 00329 if (This->pFuncsTable->pfnProcessEnd) 00330 hr = This->pFuncsTable->pfnProcessEnd(This); 00331 } 00332 LeaveCriticalSection(&This->csFilter); 00333 00334 return hr; 00335 } 00336 00337 static HRESULT WINAPI TransformFilter_Pause(IBaseFilter * iface) 00338 { 00339 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00340 HRESULT hr; 00341 00342 TRACE("(%p/%p)->()\n", This, iface); 00343 00344 EnterCriticalSection(&This->csFilter); 00345 { 00346 if (This->state == State_Stopped) 00347 hr = IBaseFilter_Run(iface, -1); 00348 else 00349 hr = S_OK; 00350 00351 if (SUCCEEDED(hr)) 00352 This->state = State_Paused; 00353 } 00354 LeaveCriticalSection(&This->csFilter); 00355 00356 return hr; 00357 } 00358 00359 static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tStart) 00360 { 00361 HRESULT hr = S_OK; 00362 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00363 00364 TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); 00365 00366 EnterCriticalSection(&This->csFilter); 00367 { 00368 if (This->state == State_Stopped) 00369 { 00370 ((InputPin *)This->ppPins[0])->end_of_stream = 0; 00371 if (This->pFuncsTable->pfnProcessBegin) 00372 hr = This->pFuncsTable->pfnProcessBegin(This); 00373 if (SUCCEEDED(hr)) 00374 hr = OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]); 00375 } 00376 00377 if (SUCCEEDED(hr)) 00378 { 00379 This->rtStreamStart = tStart; 00380 This->state = State_Running; 00381 } 00382 } 00383 LeaveCriticalSection(&This->csFilter); 00384 00385 return hr; 00386 } 00387 00388 static HRESULT WINAPI TransformFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) 00389 { 00390 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00391 00392 TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); 00393 00394 EnterCriticalSection(&This->csFilter); 00395 { 00396 *pState = This->state; 00397 } 00398 LeaveCriticalSection(&This->csFilter); 00399 00400 return S_OK; 00401 } 00402 00403 static HRESULT WINAPI TransformFilter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) 00404 { 00405 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00406 00407 TRACE("(%p/%p)->(%p)\n", This, iface, pClock); 00408 00409 EnterCriticalSection(&This->csFilter); 00410 { 00411 if (This->pClock) 00412 IReferenceClock_Release(This->pClock); 00413 This->pClock = pClock; 00414 if (This->pClock) 00415 IReferenceClock_AddRef(This->pClock); 00416 } 00417 LeaveCriticalSection(&This->csFilter); 00418 00419 return S_OK; 00420 } 00421 00422 static HRESULT WINAPI TransformFilter_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) 00423 { 00424 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00425 00426 TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); 00427 00428 EnterCriticalSection(&This->csFilter); 00429 { 00430 *ppClock = This->pClock; 00431 if (This->pClock) 00432 IReferenceClock_AddRef(This->pClock); 00433 } 00434 LeaveCriticalSection(&This->csFilter); 00435 00436 return S_OK; 00437 } 00438 00441 static HRESULT TransformFilter_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) 00442 { 00443 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00444 00445 /* Our pins are static, not changing so setting static tick count is ok */ 00446 *lastsynctick = 0; 00447 00448 if (pos >= This->npins) 00449 return S_FALSE; 00450 00451 *pin = This->ppPins[pos]; 00452 IPin_AddRef(*pin); 00453 return S_OK; 00454 } 00455 00456 static HRESULT WINAPI TransformFilter_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) 00457 { 00458 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00459 00460 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); 00461 00462 return IEnumPinsImpl_Construct(ppEnum, TransformFilter_GetPin, iface); 00463 } 00464 00465 static HRESULT WINAPI TransformFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) 00466 { 00467 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00468 00469 TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin); 00470 00471 return E_NOTIMPL; 00472 } 00473 00474 static HRESULT WINAPI TransformFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) 00475 { 00476 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00477 00478 TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); 00479 00480 strcpyW(pInfo->achName, This->filterInfo.achName); 00481 pInfo->pGraph = This->filterInfo.pGraph; 00482 00483 if (pInfo->pGraph) 00484 IFilterGraph_AddRef(pInfo->pGraph); 00485 00486 return S_OK; 00487 } 00488 00489 static HRESULT WINAPI TransformFilter_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) 00490 { 00491 HRESULT hr = S_OK; 00492 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00493 00494 TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); 00495 00496 EnterCriticalSection(&This->csFilter); 00497 { 00498 if (pName) 00499 strcpyW(This->filterInfo.achName, pName); 00500 else 00501 *This->filterInfo.achName = '\0'; 00502 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ 00503 } 00504 LeaveCriticalSection(&This->csFilter); 00505 00506 return hr; 00507 } 00508 00509 static HRESULT WINAPI TransformFilter_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) 00510 { 00511 TransformFilterImpl *This = (TransformFilterImpl *)iface; 00512 TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); 00513 return E_NOTIMPL; 00514 } 00515 00516 static const IBaseFilterVtbl TransformFilter_Vtbl = 00517 { 00518 TransformFilter_QueryInterface, 00519 TransformFilter_AddRef, 00520 TransformFilter_Release, 00521 TransformFilter_GetClassID, 00522 TransformFilter_Stop, 00523 TransformFilter_Pause, 00524 TransformFilter_Run, 00525 TransformFilter_GetState, 00526 TransformFilter_SetSyncSource, 00527 TransformFilter_GetSyncSource, 00528 TransformFilter_EnumPins, 00529 TransformFilter_FindPin, 00530 TransformFilter_QueryFilterInfo, 00531 TransformFilter_JoinFilterGraph, 00532 TransformFilter_QueryVendorInfo 00533 }; 00534 00535 static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface) 00536 { 00537 InputPin* This = (InputPin*) iface; 00538 TransformFilterImpl* pTransform; 00539 IPin* ppin; 00540 HRESULT hr; 00541 00542 TRACE("(%p)->()\n", iface); 00543 00544 /* Since we process samples synchronously, just forward notification downstream */ 00545 pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; 00546 if (!pTransform) 00547 hr = E_FAIL; 00548 else 00549 hr = IPin_ConnectedTo(pTransform->ppPins[1], &ppin); 00550 if (SUCCEEDED(hr)) 00551 { 00552 hr = IPin_EndOfStream(ppin); 00553 IPin_Release(ppin); 00554 } 00555 00556 if (FAILED(hr)) 00557 ERR("%x\n", hr); 00558 return hr; 00559 } 00560 00561 static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) 00562 { 00563 InputPin* This = (InputPin*) iface; 00564 TransformFilterImpl* pTransform; 00565 HRESULT hr; 00566 00567 TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt); 00568 00569 pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; 00570 00571 hr = pTransform->pFuncsTable->pfnConnectInput(This, pmt); 00572 if (SUCCEEDED(hr)) 00573 { 00574 hr = InputPin_ReceiveConnection(iface, pReceivePin, pmt); 00575 if (FAILED(hr)) 00576 pTransform->pFuncsTable->pfnCleanup(This); 00577 } 00578 00579 return hr; 00580 } 00581 00582 static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface) 00583 { 00584 InputPin* This = (InputPin*) iface; 00585 TransformFilterImpl* pTransform; 00586 00587 TRACE("(%p)->()\n", iface); 00588 00589 pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; 00590 pTransform->pFuncsTable->pfnCleanup(This); 00591 00592 return IPinImpl_Disconnect(iface); 00593 } 00594 00595 static const IPinVtbl TransformFilter_InputPin_Vtbl = 00596 { 00597 InputPin_QueryInterface, 00598 IPinImpl_AddRef, 00599 InputPin_Release, 00600 InputPin_Connect, 00601 TransformFilter_InputPin_ReceiveConnection, 00602 TransformFilter_InputPin_Disconnect, 00603 IPinImpl_ConnectedTo, 00604 IPinImpl_ConnectionMediaType, 00605 IPinImpl_QueryPinInfo, 00606 IPinImpl_QueryDirection, 00607 IPinImpl_QueryId, 00608 IPinImpl_QueryAccept, 00609 IPinImpl_EnumMediaTypes, 00610 IPinImpl_QueryInternalConnections, 00611 TransformFilter_InputPin_EndOfStream, 00612 InputPin_BeginFlush, 00613 InputPin_EndFlush, 00614 InputPin_NewSegment 00615 }; 00616 00617 static HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) 00618 { 00619 IPinImpl *This = (IPinImpl *)iface; 00620 TransformFilterImpl *pTransform = (TransformFilterImpl *)This->pinInfo.pFilter; 00621 ENUMMEDIADETAILS emd; 00622 00623 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); 00624 00625 emd.cMediaTypes = 1; 00626 emd.pMediaTypes = &pTransform->pmt; 00627 00628 return IEnumMediaTypesImpl_Construct(&emd, ppEnum); 00629 } 00630 00631 static const IPinVtbl TransformFilter_OutputPin_Vtbl = 00632 { 00633 OutputPin_QueryInterface, 00634 IPinImpl_AddRef, 00635 OutputPin_Release, 00636 OutputPin_Connect, 00637 OutputPin_ReceiveConnection, 00638 OutputPin_Disconnect, 00639 IPinImpl_ConnectedTo, 00640 IPinImpl_ConnectionMediaType, 00641 IPinImpl_QueryPinInfo, 00642 IPinImpl_QueryDirection, 00643 IPinImpl_QueryId, 00644 IPinImpl_QueryAccept, 00645 TransformFilter_Output_EnumMediaTypes, 00646 IPinImpl_QueryInternalConnections, 00647 OutputPin_EndOfStream, 00648 OutputPin_BeginFlush, 00649 OutputPin_EndFlush, 00650 OutputPin_NewSegment 00651 }; Generated on Sat May 26 2012 04:18:28 for ReactOS by
1.7.6.1
|