Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninput_pin.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy 00004 * FILE: dll/directx/ksproxy/input_pin.cpp 00005 * PURPOSE: InputPin of Proxy Filter 00006 * 00007 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) 00008 */ 00009 #include "precomp.h" 00010 00011 const GUID IID_IKsPinPipe = {0xe539cd90, 0xa8b4, 0x11d1, {0x81, 0x89, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}}; 00012 const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}}; 00013 00014 00015 #ifndef _MSC_VER 00016 00017 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00018 00019 KSPIN_INTERFACE StandardPinInterface = 00020 { 00021 {STATIC_KSINTERFACESETID_Standard}, 00022 KSINTERFACE_STANDARD_STREAMING, 00023 0 00024 }; 00025 00026 KSPIN_MEDIUM StandardPinMedium = 00027 { 00028 {STATIC_KSMEDIUMSETID_Standard}, 00029 KSMEDIUM_TYPE_ANYINSTANCE, 00030 0 00031 }; 00032 00033 #else 00034 00035 KSPIN_INTERFACE StandardPinInterface = 00036 { 00037 STATIC_KSINTERFACESETID_Standard, 00038 KSINTERFACE_STANDARD_STREAMING, 00039 0 00040 }; 00041 00042 KSPIN_MEDIUM StandardPinMedium = 00043 { 00044 STATIC_KSMEDIUMSETID_Standard, 00045 KSMEDIUM_TYPE_ANYINSTANCE, 00046 0 00047 }; 00048 00049 #endif 00050 00051 class CInputPin : public IPin, 00052 public IKsPropertySet, 00053 public IKsControl, 00054 public IKsObject, 00055 public IKsPinEx, 00056 public IMemInputPin, 00057 public IKsPinPipe, 00058 public IKsPinFactory, 00059 public IStreamBuilder, 00060 public IKsAggregateControl, 00061 public IQualityControl, 00062 public ISpecifyPropertyPages 00063 { 00064 public: 00065 typedef std::vector<IUnknown *>ProxyPluginVector; 00066 00067 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 00068 00069 STDMETHODIMP_(ULONG) AddRef() 00070 { 00071 InterlockedIncrement(&m_Ref); 00072 return m_Ref; 00073 } 00074 STDMETHODIMP_(ULONG) Release() 00075 { 00076 InterlockedDecrement(&m_Ref); 00077 if (!m_Ref) 00078 { 00079 delete this; 00080 return 0; 00081 } 00082 return m_Ref; 00083 } 00084 00085 //IKsPinPipe 00086 HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); 00087 HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); 00088 IPin* STDMETHODCALLTYPE KsGetConnectedPin(); 00089 IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation); 00090 HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator); 00091 ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag(); 00092 HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag); 00093 GUID STDMETHODCALLTYPE KsGetPinBusCache(); 00094 HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus); 00095 PWCHAR STDMETHODCALLTYPE KsGetPinName(); 00096 PWCHAR STDMETHODCALLTYPE KsGetFilterName(); 00097 00098 //IPin methods 00099 HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); 00100 HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); 00101 HRESULT STDMETHODCALLTYPE Disconnect(); 00102 HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin); 00103 HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt); 00104 HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo); 00105 HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir); 00106 HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id); 00107 HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt); 00108 HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum); 00109 HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin); 00110 HRESULT STDMETHODCALLTYPE EndOfStream(); 00111 HRESULT STDMETHODCALLTYPE BeginFlush(); 00112 HRESULT STDMETHODCALLTYPE EndFlush(); 00113 HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); 00114 00115 // ISpecifyPropertyPages 00116 HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages); 00117 00118 //IKsObject methods 00119 HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); 00120 00121 //IKsPropertySet 00122 HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); 00123 HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); 00124 HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); 00125 00126 //IKsControl 00127 HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); 00128 HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); 00129 HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); 00130 00131 //IKsPin 00132 HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList); 00133 HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList); 00134 HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium); 00135 HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium); 00136 HRESULT STDMETHODCALLTYPE KsPropagateAcquire(); 00137 HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags); 00138 HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment); 00139 IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation); 00140 HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator); 00141 HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator(); 00142 LONG STDMETHODCALLTYPE KsIncrementPendingIoCount(); 00143 LONG STDMETHODCALLTYPE KsDecrementPendingIoCount(); 00144 HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta); 00145 // IKsPinEx 00146 VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr); 00147 00148 //IMemInputPin 00149 HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator); 00150 HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); 00151 HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); 00152 HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample); 00153 HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); 00154 HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void); 00155 00156 //IKsPinFactory 00157 HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory); 00158 00159 //IStreamBuilder 00160 HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph); 00161 HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph); 00162 00163 //IKsAggregateControl 00164 HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass); 00165 HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass); 00166 00167 //IQualityControl 00168 HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q); 00169 HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc); 00170 00171 //--------------------------------------------------------------- 00172 HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt); 00173 HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt); 00174 HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt); 00175 HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids); 00176 HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids); 00177 CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication); 00178 virtual ~CInputPin(){}; 00179 00180 protected: 00181 LONG m_Ref; 00182 IBaseFilter * m_ParentFilter; 00183 LPCWSTR m_PinName; 00184 HANDLE m_hPin; 00185 ULONG m_PinId; 00186 IMemAllocator * m_MemAllocator; 00187 LONG m_IoCount; 00188 KSPIN_COMMUNICATION m_Communication; 00189 KSPIN_INTERFACE m_Interface; 00190 KSPIN_MEDIUM m_Medium; 00191 AM_MEDIA_TYPE m_MediaFormat; 00192 IPin * m_Pin; 00193 BOOL m_ReadOnly; 00194 IKsInterfaceHandler * m_InterfaceHandler; 00195 IKsAllocatorEx * m_KsAllocatorEx; 00196 ULONG m_PipeAllocatorFlag; 00197 BOOL m_bPinBusCacheInitialized; 00198 GUID m_PinBusCache; 00199 LPWSTR m_FilterName; 00200 FRAMING_PROP m_FramingProp[4]; 00201 PKSALLOCATOR_FRAMING_EX m_FramingEx[4]; 00202 ProxyPluginVector m_Plugins; 00203 }; 00204 00205 CInputPin::CInputPin( 00206 IBaseFilter * ParentFilter, 00207 LPCWSTR PinName, 00208 ULONG PinId, 00209 KSPIN_COMMUNICATION Communication) : m_Ref(0), 00210 m_ParentFilter(ParentFilter), 00211 m_PinName(PinName), 00212 m_hPin(INVALID_HANDLE_VALUE), 00213 m_PinId(PinId), 00214 m_MemAllocator(0), 00215 m_IoCount(0), 00216 m_Communication(Communication), 00217 m_Pin(0), 00218 m_ReadOnly(0), 00219 m_InterfaceHandler(0), 00220 m_KsAllocatorEx(0), 00221 m_PipeAllocatorFlag(0), 00222 m_bPinBusCacheInitialized(0), 00223 m_FilterName(0), 00224 m_Plugins() 00225 { 00226 ZeroMemory(m_FramingProp, sizeof(m_FramingProp)); 00227 ZeroMemory(m_FramingEx, sizeof(m_FramingEx)); 00228 00229 HRESULT hr; 00230 IKsObject * KsObjectParent; 00231 HANDLE hFilter; 00232 00233 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 00234 assert(hr == S_OK); 00235 00236 hFilter = KsObjectParent->KsGetObjectHandle(); 00237 assert(hFilter); 00238 00239 KsObjectParent->Release(); 00240 00241 00242 ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE)); 00243 hr = KsGetMediaType(0, &m_MediaFormat, hFilter, m_PinId); 00244 assert(hr == S_OK); 00245 } 00246 00247 HRESULT 00248 STDMETHODCALLTYPE 00249 CInputPin::QueryInterface( 00250 IN REFIID refiid, 00251 OUT PVOID* Output) 00252 { 00253 WCHAR Buffer[100]; 00254 00255 *Output = NULL; 00256 00257 if (IsEqualGUID(refiid, IID_IUnknown) || 00258 IsEqualGUID(refiid, IID_IPin)) 00259 { 00260 *Output = PVOID(this); 00261 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 00262 return NOERROR; 00263 } 00264 else if (IsEqualGUID(refiid, IID_IMemInputPin)) 00265 { 00266 if (m_hPin == INVALID_HANDLE_VALUE) 00267 { 00268 HRESULT hr = CreatePin(&m_MediaFormat); 00269 if (FAILED(hr)) 00270 return hr; 00271 } 00272 00273 *Output = (IMemInputPin*)(this); 00274 reinterpret_cast<IMemInputPin*>(*Output)->AddRef(); 00275 return NOERROR; 00276 } 00277 else if (IsEqualGUID(refiid, IID_IKsObject)) 00278 { 00279 *Output = (IKsObject*)(this); 00280 reinterpret_cast<IKsObject*>(*Output)->AddRef(); 00281 return NOERROR; 00282 } 00283 else if (IsEqualGUID(refiid, IID_IKsPropertySet)) 00284 { 00285 if (m_hPin == INVALID_HANDLE_VALUE) 00286 { 00287 HRESULT hr = CreatePin(&m_MediaFormat); 00288 if (FAILED(hr)) 00289 return hr; 00290 } 00291 00292 *Output = (IKsPropertySet*)(this); 00293 reinterpret_cast<IKsPropertySet*>(*Output)->AddRef(); 00294 return NOERROR; 00295 } 00296 else if (IsEqualGUID(refiid, IID_IKsControl)) 00297 { 00298 *Output = (IKsControl*)(this); 00299 reinterpret_cast<IKsControl*>(*Output)->AddRef(); 00300 return NOERROR; 00301 } 00302 else if (IsEqualGUID(refiid, IID_IKsPin) || 00303 IsEqualGUID(refiid, IID_IKsPinEx)) 00304 { 00305 *Output = (IKsPinEx*)(this); 00306 reinterpret_cast<IKsPinEx*>(*Output)->AddRef(); 00307 return NOERROR; 00308 } 00309 else if (IsEqualGUID(refiid, IID_IKsPinPipe)) 00310 { 00311 *Output = (IKsPinPipe*)(this); 00312 reinterpret_cast<IKsPinPipe*>(*Output)->AddRef(); 00313 return NOERROR; 00314 } 00315 else if (IsEqualGUID(refiid, IID_IKsPinFactory)) 00316 { 00317 *Output = (IKsPinFactory*)(this); 00318 reinterpret_cast<IKsPinFactory*>(*Output)->AddRef(); 00319 return NOERROR; 00320 } 00321 #if 0 00322 else if (IsEqualGUID(refiid, IID_IStreamBuilder)) 00323 { 00324 *Output = (IStreamBuilder*)(this); 00325 reinterpret_cast<IStreamBuilder*>(*Output)->AddRef(); 00326 return NOERROR; 00327 } 00328 #endif 00329 else if (IsEqualGUID(refiid, IID_IKsAggregateControl)) 00330 { 00331 *Output = (IKsAggregateControl*)(this); 00332 reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef(); 00333 return NOERROR; 00334 } 00335 else if (IsEqualGUID(refiid, IID_IQualityControl)) 00336 { 00337 *Output = (IQualityControl*)(this); 00338 reinterpret_cast<IQualityControl*>(*Output)->AddRef(); 00339 return NOERROR; 00340 } 00341 else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) 00342 { 00343 *Output = (ISpecifyPropertyPages*)(this); 00344 reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef(); 00345 return NOERROR; 00346 } 00347 00348 LPOLESTR lpstr; 00349 StringFromCLSID(refiid, &lpstr); 00350 swprintf(Buffer, L"CInputPin::QueryInterface: NoInterface for %s\n", lpstr); 00351 OutputDebugStringW(Buffer); 00352 CoTaskMemFree(lpstr); 00353 00354 return E_NOINTERFACE; 00355 } 00356 //------------------------------------------------------------------- 00357 // IQualityControl interface 00358 // 00359 HRESULT 00360 STDMETHODCALLTYPE 00361 CInputPin::Notify( 00362 IBaseFilter *pSelf, 00363 Quality q) 00364 { 00365 #ifdef KSPROXY_TRACE 00366 OutputDebugStringW(L"CInputPin::Notify NotImplemented\n"); 00367 #endif 00368 00369 return E_NOTIMPL; 00370 } 00371 00372 HRESULT 00373 STDMETHODCALLTYPE 00374 CInputPin::SetSink( 00375 IQualityControl *piqc) 00376 { 00377 #ifdef KSPROXY_TRACE 00378 OutputDebugStringW(L"CInputPin::SetSink NotImplemented\n"); 00379 #endif 00380 00381 return E_NOTIMPL; 00382 } 00383 00384 00385 //------------------------------------------------------------------- 00386 // IKsAggregateControl interface 00387 // 00388 HRESULT 00389 STDMETHODCALLTYPE 00390 CInputPin::KsAddAggregate( 00391 IN REFGUID AggregateClass) 00392 { 00393 #ifdef KSPROXY_TRACE 00394 OutputDebugStringW(L"CInputPin::KsAddAggregate NotImplemented\n"); 00395 #endif 00396 00397 return E_NOTIMPL; 00398 } 00399 00400 HRESULT 00401 STDMETHODCALLTYPE 00402 CInputPin::KsRemoveAggregate( 00403 REFGUID AggregateClass) 00404 { 00405 #ifdef KSPROXY_TRACE 00406 OutputDebugStringW(L"CInputPin::KsRemoveAggregate NotImplemented\n"); 00407 #endif 00408 00409 return E_NOTIMPL; 00410 } 00411 00412 //------------------------------------------------------------------- 00413 // IStreamBuilder 00414 // 00415 00416 HRESULT 00417 STDMETHODCALLTYPE 00418 CInputPin::Render( 00419 IPin *ppinOut, 00420 IGraphBuilder *pGraph) 00421 { 00422 OutputDebugStringW(L"CInputPin::Render\n"); 00423 return S_OK; 00424 } 00425 00426 HRESULT 00427 STDMETHODCALLTYPE 00428 CInputPin::Backout( 00429 IPin *ppinOut, 00430 IGraphBuilder *pGraph) 00431 { 00432 #ifdef KSPROXY_TRACE 00433 OutputDebugStringW(L"CInputPin::Backout\n"); 00434 #endif 00435 00436 return S_OK; 00437 } 00438 00439 //------------------------------------------------------------------- 00440 // IKsPinFactory 00441 // 00442 00443 HRESULT 00444 STDMETHODCALLTYPE 00445 CInputPin::KsPinFactory( 00446 ULONG* PinFactory) 00447 { 00448 #ifdef KSPROXY_TRACE 00449 OutputDebugStringW(L"CInputPin::KsPinFactory\n"); 00450 #endif 00451 00452 *PinFactory = m_PinId; 00453 return S_OK; 00454 } 00455 00456 //------------------------------------------------------------------- 00457 // IKsPinPipe 00458 // 00459 00460 HRESULT 00461 STDMETHODCALLTYPE 00462 CInputPin::KsGetPinFramingCache( 00463 PKSALLOCATOR_FRAMING_EX *FramingEx, 00464 PFRAMING_PROP FramingProp, 00465 FRAMING_CACHE_OPS Option) 00466 { 00467 if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast) 00468 { 00469 // invalid argument 00470 return E_INVALIDARG; 00471 } 00472 00473 // get framing properties 00474 *FramingProp = m_FramingProp[Option]; 00475 *FramingEx = m_FramingEx[Option]; 00476 00477 return NOERROR; 00478 } 00479 00480 HRESULT 00481 STDMETHODCALLTYPE 00482 CInputPin::KsSetPinFramingCache( 00483 PKSALLOCATOR_FRAMING_EX FramingEx, 00484 PFRAMING_PROP FramingProp, 00485 FRAMING_CACHE_OPS Option) 00486 { 00487 ULONG Index; 00488 ULONG RefCount = 0; 00489 00490 if (m_FramingEx[Option]) 00491 { 00492 for(Index = 1; Index < 4; Index++) 00493 { 00494 if (m_FramingEx[Index] == m_FramingEx[Option]) 00495 RefCount++; 00496 } 00497 00498 if (RefCount == 1) 00499 { 00500 // existing framing is only used once 00501 CoTaskMemFree(m_FramingEx[Option]); 00502 } 00503 } 00504 00505 // store framing 00506 m_FramingEx[Option] = FramingEx; 00507 m_FramingProp[Option] = *FramingProp; 00508 00509 return S_OK; 00510 } 00511 00512 IPin* 00513 STDMETHODCALLTYPE 00514 CInputPin::KsGetConnectedPin() 00515 { 00516 return m_Pin; 00517 } 00518 00519 IKsAllocatorEx* 00520 STDMETHODCALLTYPE 00521 CInputPin::KsGetPipe( 00522 KSPEEKOPERATION Operation) 00523 { 00524 if (Operation == KsPeekOperation_AddRef) 00525 { 00526 if (m_KsAllocatorEx) 00527 m_KsAllocatorEx->AddRef(); 00528 } 00529 return m_KsAllocatorEx; 00530 } 00531 00532 HRESULT 00533 STDMETHODCALLTYPE 00534 CInputPin::KsSetPipe( 00535 IKsAllocatorEx *KsAllocator) 00536 { 00537 if (KsAllocator) 00538 KsAllocator->AddRef(); 00539 00540 if (m_KsAllocatorEx) 00541 m_KsAllocatorEx->Release(); 00542 00543 m_KsAllocatorEx = KsAllocator; 00544 return NOERROR; 00545 } 00546 00547 ULONG 00548 STDMETHODCALLTYPE 00549 CInputPin::KsGetPipeAllocatorFlag() 00550 { 00551 return m_PipeAllocatorFlag; 00552 } 00553 00554 00555 HRESULT 00556 STDMETHODCALLTYPE 00557 CInputPin::KsSetPipeAllocatorFlag( 00558 ULONG Flag) 00559 { 00560 m_PipeAllocatorFlag = Flag; 00561 return NOERROR; 00562 } 00563 00564 GUID 00565 STDMETHODCALLTYPE 00566 CInputPin::KsGetPinBusCache() 00567 { 00568 if (!m_bPinBusCacheInitialized) 00569 { 00570 CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID)); 00571 m_bPinBusCacheInitialized = TRUE; 00572 } 00573 00574 return m_PinBusCache; 00575 } 00576 00577 HRESULT 00578 STDMETHODCALLTYPE 00579 CInputPin::KsSetPinBusCache( 00580 GUID Bus) 00581 { 00582 CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID)); 00583 return NOERROR; 00584 } 00585 00586 PWCHAR 00587 STDMETHODCALLTYPE 00588 CInputPin::KsGetPinName() 00589 { 00590 return (PWCHAR)m_PinName; 00591 } 00592 00593 00594 PWCHAR 00595 STDMETHODCALLTYPE 00596 CInputPin::KsGetFilterName() 00597 { 00598 return m_FilterName; 00599 } 00600 00601 //------------------------------------------------------------------- 00602 // ISpecifyPropertyPages 00603 // 00604 00605 HRESULT 00606 STDMETHODCALLTYPE 00607 CInputPin::GetPages(CAUUID *pPages) 00608 { 00609 if (!pPages) 00610 return E_POINTER; 00611 00612 pPages->cElems = 0; 00613 pPages->pElems = NULL; 00614 00615 return S_OK; 00616 } 00617 00618 //------------------------------------------------------------------- 00619 // IMemInputPin 00620 // 00621 00622 00623 HRESULT 00624 STDMETHODCALLTYPE 00625 CInputPin::GetAllocator(IMemAllocator **ppAllocator) 00626 { 00627 #ifdef KSPROXY_TRACE 00628 OutputDebugStringW(L"CInputPin::GetAllocator\n"); 00629 #endif 00630 00631 return VFW_E_NO_ALLOCATOR; 00632 } 00633 00634 HRESULT 00635 STDMETHODCALLTYPE 00636 CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) 00637 { 00638 HRESULT hr; 00639 ALLOCATOR_PROPERTIES Properties; 00640 00641 hr = pAllocator->GetProperties(&Properties); 00642 00643 #ifdef KSPROXY_TRACE 00644 WCHAR Buffer[100]; 00645 swprintf(Buffer, L"CInputPin::NotifyAllocator hr %lx bReadOnly, %u cbAlign %u cbBuffer %u cbPrefix %u cBuffers %u\n", hr, bReadOnly, Properties.cbAlign, Properties.cbBuffer, Properties.cbPrefix, Properties.cBuffers); 00646 OutputDebugStringW(Buffer); 00647 #endif 00648 00649 if (pAllocator) 00650 { 00651 pAllocator->AddRef(); 00652 } 00653 00654 if (m_MemAllocator) 00655 { 00656 m_MemAllocator->Release(); 00657 } 00658 00659 m_MemAllocator = pAllocator; 00660 m_ReadOnly = bReadOnly; 00661 return NOERROR; 00662 } 00663 00664 HRESULT 00665 STDMETHODCALLTYPE 00666 CInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) 00667 { 00668 KSALLOCATOR_FRAMING Framing; 00669 KSPROPERTY Property; 00670 HRESULT hr; 00671 ULONG BytesReturned; 00672 00673 Property.Set = KSPROPSETID_Connection; 00674 Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING; 00675 Property.Flags = KSPROPERTY_TYPE_SET; 00676 00677 hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned); 00678 if (SUCCEEDED(hr)) 00679 { 00680 pProps->cBuffers = Framing.Frames; 00681 pProps->cbBuffer = Framing.FrameSize; 00682 pProps->cbAlign = Framing.FileAlignment; 00683 pProps->cbPrefix = 0; 00684 } 00685 else 00686 hr = E_NOTIMPL; 00687 00688 #ifdef KSPROXY_TRACE 00689 WCHAR Buffer[100]; 00690 swprintf(Buffer, L"CInputPin::GetAllocatorRequirements hr %lx m_hPin %p cBuffers %u cbBuffer %u cbAlign %u cbPrefix %u\n", hr, m_hPin, pProps->cBuffers, pProps->cbBuffer, pProps->cbAlign, pProps->cbPrefix); 00691 OutputDebugStringW(Buffer); 00692 #endif 00693 00694 return hr; 00695 } 00696 00697 HRESULT 00698 STDMETHODCALLTYPE 00699 CInputPin::Receive(IMediaSample *pSample) 00700 { 00701 #ifdef KSPROXY_TRACE 00702 OutputDebugStringW(L"CInputPin::Receive NotImplemented\n"); 00703 #endif 00704 00705 return E_NOTIMPL; 00706 } 00707 00708 HRESULT 00709 STDMETHODCALLTYPE 00710 CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) 00711 { 00712 #ifdef KSPROXY_TRACE 00713 OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n"); 00714 #endif 00715 00716 return E_NOTIMPL; 00717 } 00718 00719 HRESULT 00720 STDMETHODCALLTYPE 00721 CInputPin::ReceiveCanBlock( void) 00722 { 00723 #ifdef KSPROXY_TRACE 00724 OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n"); 00725 #endif 00726 00727 return S_FALSE; 00728 } 00729 00730 //------------------------------------------------------------------- 00731 // IKsPin 00732 // 00733 00734 HRESULT 00735 STDMETHODCALLTYPE 00736 CInputPin::KsQueryMediums( 00737 PKSMULTIPLE_ITEM* MediumList) 00738 { 00739 HRESULT hr; 00740 IKsObject * KsObjectParent; 00741 HANDLE hFilter; 00742 00743 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 00744 if (FAILED(hr)) 00745 return hr; 00746 00747 hFilter = KsObjectParent->KsGetObjectHandle(); 00748 00749 KsObjectParent->Release(); 00750 00751 if (!hFilter) 00752 return E_HANDLE; 00753 00754 return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList); 00755 } 00756 00757 HRESULT 00758 STDMETHODCALLTYPE 00759 CInputPin::KsQueryInterfaces( 00760 PKSMULTIPLE_ITEM* InterfaceList) 00761 { 00762 HRESULT hr; 00763 IKsObject * KsObjectParent; 00764 HANDLE hFilter; 00765 00766 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 00767 if (FAILED(hr)) 00768 return hr; 00769 00770 hFilter = KsObjectParent->KsGetObjectHandle(); 00771 00772 KsObjectParent->Release(); 00773 00774 if (!hFilter) 00775 return E_HANDLE; 00776 00777 return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList); 00778 } 00779 00780 HRESULT 00781 STDMETHODCALLTYPE 00782 CInputPin::KsCreateSinkPinHandle( 00783 KSPIN_INTERFACE& Interface, 00784 KSPIN_MEDIUM& Medium) 00785 { 00786 return CreatePin(&m_MediaFormat); 00787 } 00788 00789 HRESULT 00790 STDMETHODCALLTYPE 00791 CInputPin::KsGetCurrentCommunication( 00792 KSPIN_COMMUNICATION *Communication, 00793 KSPIN_INTERFACE *Interface, 00794 KSPIN_MEDIUM *Medium) 00795 { 00796 if (Communication) 00797 { 00798 *Communication = m_Communication; 00799 } 00800 00801 if (Interface) 00802 { 00803 if (!m_hPin) 00804 return VFW_E_NOT_CONNECTED; 00805 00806 CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE)); 00807 } 00808 00809 if (Medium) 00810 { 00811 if (!m_hPin) 00812 return VFW_E_NOT_CONNECTED; 00813 00814 CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM)); 00815 } 00816 return NOERROR; 00817 } 00818 00819 HRESULT 00820 STDMETHODCALLTYPE 00821 CInputPin::KsPropagateAcquire() 00822 { 00823 KSPROPERTY Property; 00824 KSSTATE State; 00825 ULONG BytesReturned; 00826 HRESULT hr; 00827 00828 assert(m_hPin != INVALID_HANDLE_VALUE); 00829 00830 Property.Set = KSPROPSETID_Connection; 00831 Property.Id = KSPROPERTY_CONNECTION_STATE; 00832 Property.Flags = KSPROPERTY_TYPE_SET; 00833 00834 State = KSSTATE_ACQUIRE; 00835 00836 hr = KsProperty(&Property, sizeof(KSPROPERTY), (LPVOID)&State, sizeof(KSSTATE), &BytesReturned); 00837 00838 //TODO 00839 //propagate to connected pin on the pipe 00840 00841 return hr; 00842 } 00843 00844 HRESULT 00845 STDMETHODCALLTYPE 00846 CInputPin::KsDeliver( 00847 IMediaSample* Sample, 00848 ULONG Flags) 00849 { 00850 return E_FAIL; 00851 } 00852 00853 HRESULT 00854 STDMETHODCALLTYPE 00855 CInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment) 00856 { 00857 return NOERROR; 00858 } 00859 00860 IMemAllocator * 00861 STDMETHODCALLTYPE 00862 CInputPin::KsPeekAllocator(KSPEEKOPERATION Operation) 00863 { 00864 if (Operation == KsPeekOperation_AddRef) 00865 { 00866 // add reference on allocator 00867 m_MemAllocator->AddRef(); 00868 } 00869 00870 return m_MemAllocator; 00871 } 00872 00873 HRESULT 00874 STDMETHODCALLTYPE 00875 CInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator) 00876 { 00877 00878 if (MemAllocator) 00879 { 00880 MemAllocator->AddRef(); 00881 } 00882 00883 if (m_MemAllocator) 00884 { 00885 m_MemAllocator->Release(); 00886 } 00887 00888 m_MemAllocator = MemAllocator; 00889 return NOERROR; 00890 } 00891 00892 HRESULT 00893 STDMETHODCALLTYPE 00894 CInputPin::KsRenegotiateAllocator() 00895 { 00896 return E_FAIL; 00897 } 00898 00899 LONG 00900 STDMETHODCALLTYPE 00901 CInputPin::KsIncrementPendingIoCount() 00902 { 00903 return InterlockedIncrement((volatile LONG*)&m_IoCount); 00904 } 00905 00906 LONG 00907 STDMETHODCALLTYPE 00908 CInputPin::KsDecrementPendingIoCount() 00909 { 00910 return InterlockedDecrement((volatile LONG*)&m_IoCount); 00911 } 00912 00913 HRESULT 00914 STDMETHODCALLTYPE 00915 CInputPin::KsQualityNotify( 00916 ULONG Proportion, 00917 REFERENCE_TIME TimeDelta) 00918 { 00919 #ifdef KSPROXY_TRACE 00920 OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n"); 00921 #endif 00922 00923 return E_NOTIMPL; 00924 } 00925 00926 //------------------------------------------------------------------- 00927 // IKsPinEx 00928 // 00929 00930 VOID 00931 STDMETHODCALLTYPE 00932 CInputPin::KsNotifyError( 00933 IMediaSample* Sample, 00934 HRESULT hr) 00935 { 00936 #ifdef KSPROXY_TRACE 00937 OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n"); 00938 #endif 00939 } 00940 00941 00942 //------------------------------------------------------------------- 00943 // IKsControl 00944 // 00945 HRESULT 00946 STDMETHODCALLTYPE 00947 CInputPin::KsProperty( 00948 PKSPROPERTY Property, 00949 ULONG PropertyLength, 00950 LPVOID PropertyData, 00951 ULONG DataLength, 00952 ULONG* BytesReturned) 00953 { 00954 assert(m_hPin != INVALID_HANDLE_VALUE); 00955 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); 00956 } 00957 00958 HRESULT 00959 STDMETHODCALLTYPE 00960 CInputPin::KsMethod( 00961 PKSMETHOD Method, 00962 ULONG MethodLength, 00963 LPVOID MethodData, 00964 ULONG DataLength, 00965 ULONG* BytesReturned) 00966 { 00967 assert(m_hPin != INVALID_HANDLE_VALUE); 00968 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); 00969 } 00970 00971 HRESULT 00972 STDMETHODCALLTYPE 00973 CInputPin::KsEvent( 00974 PKSEVENT Event, 00975 ULONG EventLength, 00976 LPVOID EventData, 00977 ULONG DataLength, 00978 ULONG* BytesReturned) 00979 { 00980 assert(m_hPin != INVALID_HANDLE_VALUE); 00981 00982 if (EventLength) 00983 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); 00984 else 00985 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); 00986 } 00987 00988 00989 //------------------------------------------------------------------- 00990 // IKsPropertySet 00991 // 00992 HRESULT 00993 STDMETHODCALLTYPE 00994 CInputPin::Set( 00995 REFGUID guidPropSet, 00996 DWORD dwPropID, 00997 LPVOID pInstanceData, 00998 DWORD cbInstanceData, 00999 LPVOID pPropData, 01000 DWORD cbPropData) 01001 { 01002 ULONG BytesReturned; 01003 01004 if (cbInstanceData) 01005 { 01006 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); 01007 if (!Property) 01008 return E_OUTOFMEMORY; 01009 01010 Property->Set = guidPropSet; 01011 Property->Id = dwPropID; 01012 Property->Flags = KSPROPERTY_TYPE_SET; 01013 01014 CopyMemory((Property+1), pInstanceData, cbInstanceData); 01015 01016 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); 01017 CoTaskMemFree(Property); 01018 return hr; 01019 } 01020 else 01021 { 01022 KSPROPERTY Property; 01023 01024 Property.Set = guidPropSet; 01025 Property.Id = dwPropID; 01026 Property.Flags = KSPROPERTY_TYPE_SET; 01027 01028 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); 01029 return hr; 01030 } 01031 } 01032 01033 HRESULT 01034 STDMETHODCALLTYPE 01035 CInputPin::Get( 01036 REFGUID guidPropSet, 01037 DWORD dwPropID, 01038 LPVOID pInstanceData, 01039 DWORD cbInstanceData, 01040 LPVOID pPropData, 01041 DWORD cbPropData, 01042 DWORD *pcbReturned) 01043 { 01044 ULONG BytesReturned; 01045 01046 if (cbInstanceData) 01047 { 01048 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); 01049 if (!Property) 01050 return E_OUTOFMEMORY; 01051 01052 Property->Set = guidPropSet; 01053 Property->Id = dwPropID; 01054 Property->Flags = KSPROPERTY_TYPE_GET; 01055 01056 CopyMemory((Property+1), pInstanceData, cbInstanceData); 01057 01058 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); 01059 CoTaskMemFree(Property); 01060 return hr; 01061 } 01062 else 01063 { 01064 KSPROPERTY Property; 01065 01066 Property.Set = guidPropSet; 01067 Property.Id = dwPropID; 01068 Property.Flags = KSPROPERTY_TYPE_GET; 01069 01070 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); 01071 return hr; 01072 } 01073 } 01074 01075 HRESULT 01076 STDMETHODCALLTYPE 01077 CInputPin::QuerySupported( 01078 REFGUID guidPropSet, 01079 DWORD dwPropID, 01080 DWORD *pTypeSupport) 01081 { 01082 KSPROPERTY Property; 01083 ULONG BytesReturned; 01084 01085 Property.Set = guidPropSet; 01086 Property.Id = dwPropID; 01087 Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; 01088 01089 return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned); 01090 } 01091 01092 01093 //------------------------------------------------------------------- 01094 // IKsObject 01095 // 01096 HANDLE 01097 STDMETHODCALLTYPE 01098 CInputPin::KsGetObjectHandle() 01099 { 01100 assert(m_hPin); 01101 return m_hPin; 01102 } 01103 01104 //------------------------------------------------------------------- 01105 // IPin interface 01106 // 01107 HRESULT 01108 STDMETHODCALLTYPE 01109 CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) 01110 { 01111 #ifdef KSPROXY_TRACE 01112 OutputDebugStringW(L"CInputPin::Connect NotImplemented\n"); 01113 #endif 01114 return NOERROR; 01115 } 01116 01117 HRESULT 01118 STDMETHODCALLTYPE 01119 CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) 01120 { 01121 HRESULT hr; 01122 01123 if (m_Pin) 01124 { 01125 // already connected 01126 return VFW_E_ALREADY_CONNECTED; 01127 } 01128 01129 // first check format 01130 hr = CheckFormat(pmt); 01131 if (FAILED(hr)) 01132 { 01133 // format is not supported 01134 return hr; 01135 } 01136 01137 hr = CreatePin(pmt); 01138 if (FAILED(hr)) 01139 { 01140 return hr; 01141 } 01142 01143 m_Pin = pConnector; 01144 m_Pin->AddRef(); 01145 01146 return S_OK; 01147 } 01148 HRESULT 01149 STDMETHODCALLTYPE 01150 CInputPin::Disconnect( void) 01151 { 01152 if (!m_Pin) 01153 { 01154 // pin was not connected 01155 return S_FALSE; 01156 } 01157 01158 //FIXME 01159 //check if filter is active 01160 01161 m_Pin->Release(); 01162 m_Pin = NULL; 01163 01164 #ifdef KSPROXY_TRACE 01165 OutputDebugStringW(L"CInputPin::Disconnect\n"); 01166 #endif 01167 01168 return S_OK; 01169 } 01170 HRESULT 01171 STDMETHODCALLTYPE 01172 CInputPin::ConnectedTo(IPin **pPin) 01173 { 01174 if (!pPin) 01175 return E_POINTER; 01176 01177 if (m_Pin) 01178 { 01179 // increment reference count 01180 m_Pin->AddRef(); 01181 *pPin = m_Pin; 01182 return S_OK; 01183 } 01184 01185 *pPin = NULL; 01186 return VFW_E_NOT_CONNECTED; 01187 } 01188 HRESULT 01189 STDMETHODCALLTYPE 01190 CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) 01191 { 01192 if (!m_Pin) 01193 return VFW_E_NOT_CONNECTED; 01194 01195 #ifdef KSPROXY_TRACE 01196 OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); 01197 #endif 01198 01199 return E_NOTIMPL; 01200 } 01201 HRESULT 01202 STDMETHODCALLTYPE 01203 CInputPin::QueryPinInfo(PIN_INFO *pInfo) 01204 { 01205 wcscpy(pInfo->achName, m_PinName); 01206 pInfo->dir = PINDIR_INPUT; 01207 pInfo->pFilter = m_ParentFilter; 01208 m_ParentFilter->AddRef(); 01209 01210 return S_OK; 01211 } 01212 HRESULT 01213 STDMETHODCALLTYPE 01214 CInputPin::QueryDirection(PIN_DIRECTION *pPinDir) 01215 { 01216 if (pPinDir) 01217 { 01218 *pPinDir = PINDIR_INPUT; 01219 return S_OK; 01220 } 01221 01222 return E_POINTER; 01223 } 01224 HRESULT 01225 STDMETHODCALLTYPE 01226 CInputPin::QueryId(LPWSTR *Id) 01227 { 01228 *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR)); 01229 if (!*Id) 01230 return E_OUTOFMEMORY; 01231 01232 wcscpy(*Id, m_PinName); 01233 return S_OK; 01234 } 01235 01236 HRESULT 01237 STDMETHODCALLTYPE 01238 CInputPin::QueryAccept( 01239 const AM_MEDIA_TYPE *pmt) 01240 { 01241 return CheckFormat(pmt); 01242 } 01243 HRESULT 01244 STDMETHODCALLTYPE 01245 CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) 01246 { 01247 HRESULT hr; 01248 ULONG MediaTypeCount = 0, Index; 01249 AM_MEDIA_TYPE * MediaTypes; 01250 IKsObject * KsObjectParent; 01251 HANDLE hFilter; 01252 01253 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 01254 if (FAILED(hr)) 01255 return hr; 01256 01257 hFilter = KsObjectParent->KsGetObjectHandle(); 01258 01259 KsObjectParent->Release(); 01260 01261 if (!hFilter) 01262 return E_HANDLE; 01263 01264 01265 // query media type count 01266 hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount); 01267 if (FAILED(hr) || !MediaTypeCount) 01268 return hr; 01269 01270 // allocate media types 01271 MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); 01272 if (!MediaTypes) 01273 { 01274 // not enough memory 01275 return E_OUTOFMEMORY; 01276 } 01277 01278 // zero media types 01279 ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount); 01280 01281 for(Index = 0; Index < MediaTypeCount; Index++) 01282 { 01283 // get media type 01284 hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId); 01285 if (FAILED(hr)) 01286 { 01287 // failed 01288 CoTaskMemFree(MediaTypes); 01289 return hr; 01290 } 01291 } 01292 01293 return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum); 01294 } 01295 01296 HRESULT 01297 STDMETHODCALLTYPE 01298 CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) 01299 { 01300 #ifdef KSPROXY_TRACE 01301 OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n"); 01302 #endif 01303 return E_NOTIMPL; 01304 } 01305 HRESULT 01306 STDMETHODCALLTYPE 01307 CInputPin::EndOfStream( void) 01308 { 01309 #ifdef KSPROXY_TRACE 01310 OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n"); 01311 #endif 01312 return E_NOTIMPL; 01313 } 01314 HRESULT 01315 STDMETHODCALLTYPE 01316 CInputPin::BeginFlush( void) 01317 { 01318 #ifdef KSPROXY_TRACE 01319 OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n"); 01320 #endif 01321 return E_NOTIMPL; 01322 } 01323 HRESULT 01324 STDMETHODCALLTYPE 01325 CInputPin::EndFlush( void) 01326 { 01327 #ifdef KSPROXY_TRACE 01328 OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n"); 01329 #endif 01330 return E_NOTIMPL; 01331 } 01332 HRESULT 01333 STDMETHODCALLTYPE 01334 CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) 01335 { 01336 #ifdef KSPROXY_TRACE 01337 OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n"); 01338 #endif 01339 return E_NOTIMPL; 01340 } 01341 01342 01343 //------------------------------------------------------------------- 01344 HRESULT 01345 STDMETHODCALLTYPE 01346 CInputPin::CheckFormat( 01347 const AM_MEDIA_TYPE *pmt) 01348 { 01349 PKSMULTIPLE_ITEM MultipleItem; 01350 PKSDATAFORMAT DataFormat; 01351 HRESULT hr; 01352 IKsObject * KsObjectParent; 01353 HANDLE hFilter; 01354 01355 if (!pmt) 01356 return E_POINTER; 01357 01358 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 01359 if (FAILED(hr)) 01360 return hr; 01361 01362 hFilter = KsObjectParent->KsGetObjectHandle(); 01363 01364 KsObjectParent->Release(); 01365 01366 if (!hFilter) 01367 return E_HANDLE; 01368 01369 01370 hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem); 01371 if (FAILED(hr)) 01372 return S_FALSE; 01373 01374 DataFormat = (PKSDATAFORMAT)(MultipleItem + 1); 01375 for(ULONG Index = 0; Index < MultipleItem->Count; Index++) 01376 { 01377 if (IsEqualGUID(pmt->majortype, DataFormat->MajorFormat) && 01378 IsEqualGUID(pmt->subtype, DataFormat->SubFormat) && 01379 IsEqualGUID(pmt->formattype, DataFormat->Specifier)) 01380 { 01381 // format is supported 01382 CoTaskMemFree(MultipleItem); 01383 #ifdef KSPROXY_TRACE 01384 OutputDebugStringW(L"CInputPin::CheckFormat format OK\n"); 01385 #endif 01386 return S_OK; 01387 } 01388 DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); 01389 } 01390 //format is not supported 01391 CoTaskMemFree(MultipleItem); 01392 return S_FALSE; 01393 } 01394 01395 HRESULT 01396 STDMETHODCALLTYPE 01397 CInputPin::CreatePin( 01398 const AM_MEDIA_TYPE *pmt) 01399 { 01400 PKSMULTIPLE_ITEM MediumList; 01401 PKSMULTIPLE_ITEM InterfaceList; 01402 PKSPIN_MEDIUM Medium; 01403 PKSPIN_INTERFACE Interface; 01404 IKsInterfaceHandler * InterfaceHandler; 01405 HRESULT hr; 01406 01407 // query for pin medium 01408 hr = KsQueryMediums(&MediumList); 01409 if (FAILED(hr)) 01410 return hr; 01411 01412 // query for pin interface 01413 hr = KsQueryInterfaces(&InterfaceList); 01414 if (FAILED(hr)) 01415 { 01416 // failed 01417 CoTaskMemFree(MediumList); 01418 return hr; 01419 } 01420 01421 if (MediumList->Count) 01422 { 01423 //use first available medium 01424 Medium = (PKSPIN_MEDIUM)(MediumList + 1); 01425 } 01426 else 01427 { 01428 // default to standard medium 01429 Medium = &StandardPinMedium; 01430 } 01431 01432 if (InterfaceList->Count) 01433 { 01434 //use first available interface 01435 Interface = (PKSPIN_INTERFACE)(InterfaceList + 1); 01436 } 01437 else 01438 { 01439 // default to standard interface 01440 Interface = &StandardPinInterface; 01441 } 01442 01443 if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE) 01444 { 01445 if (!m_InterfaceHandler) 01446 { 01447 // now load the IKsInterfaceHandler plugin 01448 hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler); 01449 if (FAILED(hr)) 01450 { 01451 // failed to load interface handler plugin 01452 #ifdef KSPROXY_TRACE 01453 OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n"); 01454 #endif 01455 CoTaskMemFree(MediumList); 01456 CoTaskMemFree(InterfaceList); 01457 01458 return hr; 01459 } 01460 01461 // now set the pin 01462 hr = InterfaceHandler->KsSetPin((IKsPin*)this); 01463 if (FAILED(hr)) 01464 { 01465 // failed to load interface handler plugin 01466 #ifdef KSPROXY_TRACE 01467 OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n"); 01468 #endif 01469 InterfaceHandler->Release(); 01470 CoTaskMemFree(MediumList); 01471 CoTaskMemFree(InterfaceList); 01472 return hr; 01473 } 01474 01475 // store interface handler 01476 m_InterfaceHandler = InterfaceHandler; 01477 } 01478 01479 // now create pin 01480 hr = CreatePinHandle(Medium, Interface, pmt); 01481 if (FAILED(hr)) 01482 { 01483 m_InterfaceHandler->Release(); 01484 m_InterfaceHandler = InterfaceHandler; 01485 } 01486 } 01487 else 01488 { 01489 #ifdef KSPROXY_TRACE 01490 WCHAR Buffer[100]; 01491 swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); 01492 OutputDebugStringW(Buffer); 01493 #endif 01494 hr = E_FAIL; 01495 } 01496 01497 // free medium / interface / dataformat 01498 CoTaskMemFree(MediumList); 01499 CoTaskMemFree(InterfaceList); 01500 01501 return hr; 01502 } 01503 01504 HRESULT 01505 STDMETHODCALLTYPE 01506 CInputPin::CreatePinHandle( 01507 PKSPIN_MEDIUM Medium, 01508 PKSPIN_INTERFACE Interface, 01509 const AM_MEDIA_TYPE *pmt) 01510 { 01511 PKSPIN_CONNECT PinConnect; 01512 PKSDATAFORMAT DataFormat; 01513 ULONG Length; 01514 HRESULT hr; 01515 IKsObject * KsObjectParent; 01516 HANDLE hFilter; 01517 01518 if (!pmt) 01519 return E_POINTER; 01520 01521 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); 01522 if (FAILED(hr)) 01523 return hr; 01524 01525 hFilter = KsObjectParent->KsGetObjectHandle(); 01526 01527 KsObjectParent->Release(); 01528 01529 if (!hFilter) 01530 return E_HANDLE; 01531 01532 01533 if (m_hPin != INVALID_HANDLE_VALUE) 01534 { 01535 // pin already exists 01536 //CloseHandle(m_hPin); 01537 //m_hPin = INVALID_HANDLE_VALUE; 01538 return S_OK; 01539 } 01540 01541 01542 // calc format size 01543 Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat; 01544 01545 // allocate pin connect 01546 PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length); 01547 if (!PinConnect) 01548 { 01549 // failed 01550 return E_OUTOFMEMORY; 01551 } 01552 01553 // setup request 01554 CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE)); 01555 CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM)); 01556 PinConnect->PinId = m_PinId; 01557 PinConnect->PinToHandle = NULL; 01558 PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; 01559 PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL; 01560 01561 // get dataformat offset 01562 DataFormat = (PKSDATAFORMAT)(PinConnect + 1); 01563 01564 // copy data format 01565 DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat; 01566 DataFormat->Flags = 0; 01567 DataFormat->SampleSize = pmt->lSampleSize; 01568 DataFormat->Reserved = 0; 01569 CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID)); 01570 CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID)); 01571 CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID)); 01572 01573 if (pmt->cbFormat) 01574 { 01575 // copy extended format 01576 CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat); 01577 } 01578 01579 // create pin 01580 hr = KsCreatePin(hFilter, PinConnect, GENERIC_WRITE, &m_hPin); 01581 01582 if (SUCCEEDED(hr)) 01583 { 01584 // store current interface / medium 01585 CopyMemory(&m_Medium, Medium, sizeof(KSPIN_MEDIUM)); 01586 CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE)); 01587 CopyMemory(&m_MediaFormat, pmt, sizeof(AM_MEDIA_TYPE)); 01588 01589 #ifdef KSPROXY_TRACE 01590 LPOLESTR pMajor, pSub, pFormat; 01591 StringFromIID(m_MediaFormat.majortype, &pMajor); 01592 StringFromIID(m_MediaFormat.subtype , &pSub); 01593 StringFromIID(m_MediaFormat.formattype, &pFormat); 01594 01595 WCHAR Buffer[200]; 01596 swprintf(Buffer, L"CInputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor, pSub, pFormat, pmt->pbFormat, pmt->cbFormat); 01597 CoTaskMemFree(pMajor); 01598 CoTaskMemFree(pSub); 01599 CoTaskMemFree(pFormat); 01600 OutputDebugStringW(Buffer); 01601 #endif 01602 01603 if (pmt->cbFormat) 01604 { 01605 m_MediaFormat.pbFormat = (BYTE*)CoTaskMemAlloc(pmt->cbFormat); 01606 if (!m_MediaFormat.pbFormat) 01607 { 01608 CoTaskMemFree(PinConnect); 01609 m_MediaFormat.pbFormat = NULL; 01610 m_MediaFormat.cbFormat = 0; 01611 return E_OUTOFMEMORY; 01612 } 01613 CopyMemory(m_MediaFormat.pbFormat, pmt->pbFormat, pmt->cbFormat); 01614 } 01615 01616 LPGUID pGuid; 01617 ULONG NumGuids = 0; 01618 01619 // get all supported sets 01620 hr = GetSupportedSets(&pGuid, &NumGuids); 01621 if (FAILED(hr)) 01622 { 01623 #ifdef KSPROXY_TRACE 01624 OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n"); 01625 #endif 01626 return hr; 01627 } 01628 01629 // load all proxy plugins 01630 hr = LoadProxyPlugins(pGuid, NumGuids); 01631 if (FAILED(hr)) 01632 { 01633 #ifdef KSPROXY_TRACE 01634 OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n"); 01635 #endif 01636 return hr; 01637 } 01638 01639 // free sets 01640 CoTaskMemFree(pGuid); 01641 01642 01643 //TODO 01644 // connect pin pipes 01645 01646 } 01647 01648 // free pin connect 01649 CoTaskMemFree(PinConnect); 01650 01651 return hr; 01652 } 01653 01654 HRESULT 01655 STDMETHODCALLTYPE 01656 CInputPin::GetSupportedSets( 01657 LPGUID * pOutGuid, 01658 PULONG NumGuids) 01659 { 01660 KSPROPERTY Property; 01661 LPGUID pGuid; 01662 ULONG NumProperty = 0; 01663 ULONG NumMethods = 0; 01664 ULONG NumEvents = 0; 01665 ULONG Length; 01666 ULONG BytesReturned; 01667 HRESULT hr; 01668 01669 Property.Set = GUID_NULL; 01670 Property.Id = 0; 01671 Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; 01672 01673 KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty); 01674 KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods); 01675 KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents); 01676 01677 Length = NumProperty + NumMethods + NumEvents; 01678 01679 assert(Length); 01680 01681 // allocate guid buffer 01682 pGuid = (LPGUID)CoTaskMemAlloc(Length); 01683 if (!pGuid) 01684 { 01685 // failed 01686 return E_OUTOFMEMORY; 01687 } 01688 01689 NumProperty /= sizeof(GUID); 01690 NumMethods /= sizeof(GUID); 01691 NumEvents /= sizeof(GUID); 01692 01693 #ifdef KSPROXY_TRACE 01694 WCHAR Buffer[200]; 01695 swprintf(Buffer, L"CInputPin::GetSupportedSets NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents); 01696 OutputDebugStringW(Buffer); 01697 #endif 01698 01699 // get all properties 01700 hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned); 01701 if (FAILED(hr)) 01702 { 01703 CoTaskMemFree(pGuid); 01704 return E_FAIL; 01705 } 01706 Length -= BytesReturned; 01707 01708 // get all methods 01709 if (Length && NumMethods) 01710 { 01711 hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned); 01712 if (FAILED(hr)) 01713 { 01714 CoTaskMemFree(pGuid); 01715 return E_FAIL; 01716 } 01717 Length -= BytesReturned; 01718 } 01719 01720 // get all events 01721 if (Length && NumEvents) 01722 { 01723 hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned); 01724 if (FAILED(hr)) 01725 { 01726 CoTaskMemFree(pGuid); 01727 return E_FAIL; 01728 } 01729 Length -= BytesReturned; 01730 } 01731 01732 *pOutGuid = pGuid; 01733 *NumGuids = NumProperty+NumEvents+NumMethods; 01734 return S_OK; 01735 } 01736 01737 HRESULT 01738 STDMETHODCALLTYPE 01739 CInputPin::LoadProxyPlugins( 01740 LPGUID pGuids, 01741 ULONG NumGuids) 01742 { 01743 ULONG Index; 01744 LPOLESTR pStr; 01745 HKEY hKey, hSubKey; 01746 HRESULT hr; 01747 IUnknown * pUnknown; 01748 01749 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS) 01750 { 01751 OutputDebugStringW(L"CInputPin::LoadProxyPlugins failed to open MediaInterfaces key\n"); 01752 return E_FAIL; 01753 } 01754 01755 // enumerate all sets 01756 for(Index = 0; Index < NumGuids; Index++) 01757 { 01758 // convert to string 01759 hr = StringFromCLSID(pGuids[Index], &pStr); 01760 if (FAILED(hr)) 01761 return E_FAIL; 01762 01763 // now try open class key 01764 if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) 01765 { 01766 // no plugin for that set exists 01767 CoTaskMemFree(pStr); 01768 continue; 01769 } 01770 01771 // try load plugin 01772 hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown); 01773 if (SUCCEEDED(hr)) 01774 { 01775 // store plugin 01776 m_Plugins.push_back(pUnknown); 01777 } 01778 // close key 01779 RegCloseKey(hSubKey); 01780 } 01781 01782 // close media interfaces key 01783 RegCloseKey(hKey); 01784 return S_OK; 01785 } 01786 01787 HRESULT 01788 WINAPI 01789 CInputPin_Constructor( 01790 IBaseFilter * ParentFilter, 01791 LPCWSTR PinName, 01792 HANDLE hFilter, 01793 ULONG PinId, 01794 KSPIN_COMMUNICATION Communication, 01795 REFIID riid, 01796 LPVOID * ppv) 01797 { 01798 CInputPin * handler = new CInputPin(ParentFilter, PinName, PinId, Communication); 01799 01800 if (!handler) 01801 return E_OUTOFMEMORY; 01802 01803 if (FAILED(handler->QueryInterface(riid, ppv))) 01804 { 01805 /* not supported */ 01806 delete handler; 01807 return E_NOINTERFACE; 01808 } 01809 01810 return S_OK; 01811 } Generated on Sun May 27 2012 04:21:51 for ReactOS by
1.7.6.1
|