ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

input_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.