Something went wrong. Try again.
Reactos
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy * FILE: dll/directx/ksproxy/input_pin.cpp * PURPOSE: InputPin of Proxy Filter * * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) */#include "precomp.h"
const GUID IID_IKsPinPipe = {0xe539cd90, 0xa8b4, 0x11d1, {0x81, 0x89, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}};const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
KSPIN_INTERFACE StandardPinInterface ={ {STATIC_KSINTERFACESETID_Standard}, KSINTERFACE_STANDARD_STREAMING, 0};
KSPIN_MEDIUM StandardPinMedium ={ {STATIC_KSMEDIUMSETID_Standard}, KSMEDIUM_TYPE_ANYINSTANCE, 0};
class CInputPin : public IPin, public IKsPropertySet, public IKsControl, public IKsObject, public IKsPinEx, public IMemInputPin, public IKsPinPipe, public IKsPinFactory, public IStreamBuilder, public IKsAggregateControl, public IQualityControl, public ISpecifyPropertyPages{public: typedef std::vector<IUnknown *>ProxyPluginVector;
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
STDMETHODIMP_(ULONG) AddRef() { InterlockedIncrement(&m_Ref); return m_Ref; } STDMETHODIMP_(ULONG) Release() { InterlockedDecrement(&m_Ref); if (!m_Ref) { delete this; return 0; } return m_Ref; }
//IKsPinPipe HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); IPin* STDMETHODCALLTYPE KsGetConnectedPin(); IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation); HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator); ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag(); HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag); GUID STDMETHODCALLTYPE KsGetPinBusCache(); HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus); PWCHAR STDMETHODCALLTYPE KsGetPinName(); PWCHAR STDMETHODCALLTYPE KsGetFilterName();
//IPin methods HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE Disconnect(); HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin); HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo); HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir); HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id); HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum); HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin); HRESULT STDMETHODCALLTYPE EndOfStream(); HRESULT STDMETHODCALLTYPE BeginFlush(); HRESULT STDMETHODCALLTYPE EndFlush(); HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
// ISpecifyPropertyPages HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
//IKsObject methods HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
//IKsPropertySet HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);
//IKsControl HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
//IKsPin HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList); HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList); HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium); HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium); HRESULT STDMETHODCALLTYPE KsPropagateAcquire(); HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags); HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment); IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation); HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator); HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator(); LONG STDMETHODCALLTYPE KsIncrementPendingIoCount(); LONG STDMETHODCALLTYPE KsDecrementPendingIoCount(); HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta); // IKsPinEx VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr);
//IMemInputPin HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator); HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample); HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void);
//IKsPinFactory HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
//IStreamBuilder HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph); HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
//IKsAggregateControl HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass); HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
//IQualityControl HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q); HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc);
//--------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids); HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids); CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication); virtual ~CInputPin(){};
protected: LONG m_Ref; IBaseFilter * m_ParentFilter; LPCWSTR m_PinName; HANDLE m_hPin; ULONG m_PinId; IMemAllocator * m_MemAllocator; LONG m_IoCount; KSPIN_COMMUNICATION m_Communication; KSPIN_INTERFACE m_Interface; KSPIN_MEDIUM m_Medium; AM_MEDIA_TYPE m_MediaFormat; IPin * m_Pin; BOOL m_ReadOnly; IKsInterfaceHandler * m_InterfaceHandler; IKsAllocatorEx * m_KsAllocatorEx; ULONG m_PipeAllocatorFlag; BOOL m_bPinBusCacheInitialized; GUID m_PinBusCache; LPWSTR m_FilterName; FRAMING_PROP m_FramingProp[4]; PKSALLOCATOR_FRAMING_EX m_FramingEx[4]; ProxyPluginVector m_Plugins;};
CInputPin::CInputPin( IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(INVALID_HANDLE_VALUE), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0), m_ReadOnly(0), m_InterfaceHandler(0), m_KsAllocatorEx(0), m_PipeAllocatorFlag(0), m_bPinBusCacheInitialized(0), m_FilterName(0), m_Plugins(){ ZeroMemory(m_FramingProp, sizeof(m_FramingProp)); ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
HRESULT hr; IKsObject * KsObjectParent; HANDLE hFilter;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); assert(hr == S_OK);
hFilter = KsObjectParent->KsGetObjectHandle(); assert(hFilter);
KsObjectParent->Release();
ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE)); hr = KsGetMediaType(0, &m_MediaFormat, hFilter, m_PinId); assert(hr == S_OK);}
HRESULTSTDMETHODCALLTYPECInputPin::QueryInterface( IN REFIID refiid, OUT PVOID* Output){ WCHAR Buffer[100];
*Output = NULL;
if (IsEqualGUID(refiid, IID_IUnknown) || IsEqualGUID(refiid, IID_IPin)) { *Output = PVOID(this); reinterpret_cast<IUnknown*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IMemInputPin)) { if (m_hPin == INVALID_HANDLE_VALUE) { HRESULT hr = CreatePin(&m_MediaFormat); if (FAILED(hr)) return hr; }
*Output = (IMemInputPin*)(this); reinterpret_cast<IMemInputPin*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsObject)) { *Output = (IKsObject*)(this); reinterpret_cast<IKsObject*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPropertySet)) { if (m_hPin == INVALID_HANDLE_VALUE) { HRESULT hr = CreatePin(&m_MediaFormat); if (FAILED(hr)) return hr; }
*Output = (IKsPropertySet*)(this); reinterpret_cast<IKsPropertySet*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsControl)) { *Output = (IKsControl*)(this); reinterpret_cast<IKsControl*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPin) || IsEqualGUID(refiid, IID_IKsPinEx)) { *Output = (IKsPinEx*)(this); reinterpret_cast<IKsPinEx*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPinPipe)) { *Output = (IKsPinPipe*)(this); reinterpret_cast<IKsPinPipe*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPinFactory)) { *Output = (IKsPinFactory*)(this); reinterpret_cast<IKsPinFactory*>(*Output)->AddRef(); return NOERROR; }#if 0 else if (IsEqualGUID(refiid, IID_IStreamBuilder)) { *Output = (IStreamBuilder*)(this); reinterpret_cast<IStreamBuilder*>(*Output)->AddRef(); return NOERROR; }#endif else if (IsEqualGUID(refiid, IID_IKsAggregateControl)) { *Output = (IKsAggregateControl*)(this); reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IQualityControl)) { *Output = (IQualityControl*)(this); reinterpret_cast<IQualityControl*>(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) { *Output = (ISpecifyPropertyPages*)(this); reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef(); return NOERROR; }
LPOLESTR lpstr; StringFromCLSID(refiid, &lpstr); swprintf(Buffer, L"CInputPin::QueryInterface: NoInterface for %s\n", lpstr); OutputDebugStringW(Buffer); CoTaskMemFree(lpstr);
return E_NOINTERFACE;}//-------------------------------------------------------------------// IQualityControl interface//HRESULTSTDMETHODCALLTYPECInputPin::Notify( IBaseFilter *pSelf, Quality q){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Notify NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECInputPin::SetSink( IQualityControl *piqc){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::SetSink NotImplemented\n");#endif
return E_NOTIMPL;}
//-------------------------------------------------------------------// IKsAggregateControl interface//HRESULTSTDMETHODCALLTYPECInputPin::KsAddAggregate( IN REFGUID AggregateClass){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::KsAddAggregate NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECInputPin::KsRemoveAggregate( REFGUID AggregateClass){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::KsRemoveAggregate NotImplemented\n");#endif
return E_NOTIMPL;}
//-------------------------------------------------------------------// IStreamBuilder//
HRESULTSTDMETHODCALLTYPECInputPin::Render( IPin *ppinOut, IGraphBuilder *pGraph){ OutputDebugStringW(L"CInputPin::Render\n"); return S_OK;}
HRESULTSTDMETHODCALLTYPECInputPin::Backout( IPin *ppinOut, IGraphBuilder *pGraph){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Backout\n");#endif
return S_OK;}
//-------------------------------------------------------------------// IKsPinFactory//
HRESULTSTDMETHODCALLTYPECInputPin::KsPinFactory( ULONG* PinFactory){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::KsPinFactory\n");#endif
*PinFactory = m_PinId; return S_OK;}
//-------------------------------------------------------------------// IKsPinPipe//
HRESULTSTDMETHODCALLTYPECInputPin::KsGetPinFramingCache( PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option){ if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast) { // invalid argument return E_INVALIDARG; }
// get framing properties *FramingProp = m_FramingProp[Option]; *FramingEx = m_FramingEx[Option];
return NOERROR;}
HRESULTSTDMETHODCALLTYPECInputPin::KsSetPinFramingCache( PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option){ ULONG Index; ULONG RefCount = 0;
if (m_FramingEx[Option]) { for(Index = 1; Index < 4; Index++) { if (m_FramingEx[Index] == m_FramingEx[Option]) RefCount++; }
if (RefCount == 1) { // existing framing is only used once CoTaskMemFree(m_FramingEx[Option]); } }
// store framing m_FramingEx[Option] = FramingEx; m_FramingProp[Option] = *FramingProp;
return S_OK;}
IPin*STDMETHODCALLTYPECInputPin::KsGetConnectedPin(){ return m_Pin;}
IKsAllocatorEx*STDMETHODCALLTYPECInputPin::KsGetPipe( KSPEEKOPERATION Operation){ if (Operation == KsPeekOperation_AddRef) { if (m_KsAllocatorEx) m_KsAllocatorEx->AddRef(); } return m_KsAllocatorEx;}
HRESULTSTDMETHODCALLTYPECInputPin::KsSetPipe( IKsAllocatorEx *KsAllocator){ if (KsAllocator) KsAllocator->AddRef();
if (m_KsAllocatorEx) m_KsAllocatorEx->Release();
m_KsAllocatorEx = KsAllocator; return NOERROR;}
ULONGSTDMETHODCALLTYPECInputPin::KsGetPipeAllocatorFlag(){ return m_PipeAllocatorFlag;}
HRESULTSTDMETHODCALLTYPECInputPin::KsSetPipeAllocatorFlag( ULONG Flag){ m_PipeAllocatorFlag = Flag; return NOERROR;}
GUIDSTDMETHODCALLTYPECInputPin::KsGetPinBusCache(){ if (!m_bPinBusCacheInitialized) { CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID)); m_bPinBusCacheInitialized = TRUE; }
return m_PinBusCache;}
HRESULTSTDMETHODCALLTYPECInputPin::KsSetPinBusCache( GUID Bus){ CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID)); return NOERROR;}
PWCHARSTDMETHODCALLTYPECInputPin::KsGetPinName(){ return (PWCHAR)m_PinName;}
PWCHARSTDMETHODCALLTYPECInputPin::KsGetFilterName(){ return m_FilterName;}
//-------------------------------------------------------------------// ISpecifyPropertyPages//
HRESULTSTDMETHODCALLTYPECInputPin::GetPages(CAUUID *pPages){ if (!pPages) return E_POINTER;
pPages->cElems = 0; pPages->pElems = NULL;
return S_OK;}
//-------------------------------------------------------------------// IMemInputPin//
HRESULTSTDMETHODCALLTYPECInputPin::GetAllocator(IMemAllocator **ppAllocator){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::GetAllocator\n");#endif
return VFW_E_NO_ALLOCATOR;}
HRESULTSTDMETHODCALLTYPECInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly){ HRESULT hr; ALLOCATOR_PROPERTIES Properties;
hr = pAllocator->GetProperties(&Properties);
#ifdef KSPROXY_TRACE WCHAR Buffer[100]; 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); OutputDebugStringW(Buffer);#endif
if (pAllocator) { pAllocator->AddRef(); }
if (m_MemAllocator) { m_MemAllocator->Release(); }
m_MemAllocator = pAllocator; m_ReadOnly = bReadOnly; return NOERROR;}
HRESULTSTDMETHODCALLTYPECInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps){ KSALLOCATOR_FRAMING Framing; KSPROPERTY Property; HRESULT hr; ULONG BytesReturned;
Property.Set = KSPROPSETID_Connection; Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING; Property.Flags = KSPROPERTY_TYPE_SET;
hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned); if (SUCCEEDED(hr)) { pProps->cBuffers = Framing.Frames; pProps->cbBuffer = Framing.FrameSize; pProps->cbAlign = Framing.FileAlignment; pProps->cbPrefix = 0; } else hr = E_NOTIMPL;
#ifdef KSPROXY_TRACE WCHAR Buffer[100]; 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); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECInputPin::Receive(IMediaSample *pSample){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECInputPin::ReceiveCanBlock( void){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");#endif
return S_FALSE;}
//-------------------------------------------------------------------// IKsPin//
HRESULTSTDMETHODCALLTYPECInputPin::KsQueryMediums( PKSMULTIPLE_ITEM* MediumList){ HRESULT hr; IKsObject * KsObjectParent; HANDLE hFilter;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) return hr;
hFilter = KsObjectParent->KsGetObjectHandle();
KsObjectParent->Release();
if (!hFilter) return E_HANDLE;
return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);}
HRESULTSTDMETHODCALLTYPECInputPin::KsQueryInterfaces( PKSMULTIPLE_ITEM* InterfaceList){ HRESULT hr; IKsObject * KsObjectParent; HANDLE hFilter;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) return hr;
hFilter = KsObjectParent->KsGetObjectHandle();
KsObjectParent->Release();
if (!hFilter) return E_HANDLE;
return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);}
HRESULTSTDMETHODCALLTYPECInputPin::KsCreateSinkPinHandle( KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium){ return CreatePin(&m_MediaFormat);}
HRESULTSTDMETHODCALLTYPECInputPin::KsGetCurrentCommunication( KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium){ if (Communication) { *Communication = m_Communication; }
if (Interface) { if (!m_hPin) return VFW_E_NOT_CONNECTED;
CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE)); }
if (Medium) { if (!m_hPin) return VFW_E_NOT_CONNECTED;
CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM)); } return NOERROR;}
HRESULTSTDMETHODCALLTYPECInputPin::KsPropagateAcquire(){ KSPROPERTY Property; KSSTATE State; ULONG BytesReturned; HRESULT hr;
assert(m_hPin != INVALID_HANDLE_VALUE);
Property.Set = KSPROPSETID_Connection; Property.Id = KSPROPERTY_CONNECTION_STATE; Property.Flags = KSPROPERTY_TYPE_SET;
State = KSSTATE_ACQUIRE;
hr = KsProperty(&Property, sizeof(KSPROPERTY), (LPVOID)&State, sizeof(KSSTATE), &BytesReturned);
//TODO //propagate to connected pin on the pipe
return hr;}
HRESULTSTDMETHODCALLTYPECInputPin::KsDeliver( IMediaSample* Sample, ULONG Flags){ return E_FAIL;}
HRESULTSTDMETHODCALLTYPECInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment){ return NOERROR;}
IMemAllocator *STDMETHODCALLTYPECInputPin::KsPeekAllocator(KSPEEKOPERATION Operation){ if (Operation == KsPeekOperation_AddRef) { // add reference on allocator m_MemAllocator->AddRef(); }
return m_MemAllocator;}
HRESULTSTDMETHODCALLTYPECInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator){
if (MemAllocator) { MemAllocator->AddRef(); }
if (m_MemAllocator) { m_MemAllocator->Release(); }
m_MemAllocator = MemAllocator; return NOERROR;}
HRESULTSTDMETHODCALLTYPECInputPin::KsRenegotiateAllocator(){ return E_FAIL;}
LONGSTDMETHODCALLTYPECInputPin::KsIncrementPendingIoCount(){ return InterlockedIncrement((volatile LONG*)&m_IoCount);}
LONGSTDMETHODCALLTYPECInputPin::KsDecrementPendingIoCount(){ return InterlockedDecrement((volatile LONG*)&m_IoCount);}
HRESULTSTDMETHODCALLTYPECInputPin::KsQualityNotify( ULONG Proportion, REFERENCE_TIME TimeDelta){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");#endif
return E_NOTIMPL;}
//-------------------------------------------------------------------// IKsPinEx//
VOIDSTDMETHODCALLTYPECInputPin::KsNotifyError( IMediaSample* Sample, HRESULT hr){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n");#endif}
//-------------------------------------------------------------------// IKsControl//HRESULTSTDMETHODCALLTYPECInputPin::KsProperty( PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned){ assert(m_hPin != INVALID_HANDLE_VALUE); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);}
HRESULTSTDMETHODCALLTYPECInputPin::KsMethod( PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned){ assert(m_hPin != INVALID_HANDLE_VALUE); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);}
HRESULTSTDMETHODCALLTYPECInputPin::KsEvent( PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned){ assert(m_hPin != INVALID_HANDLE_VALUE);
if (EventLength) return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); else return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);}
//-------------------------------------------------------------------// IKsPropertySet//HRESULTSTDMETHODCALLTYPECInputPin::Set( REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData){ ULONG BytesReturned;
if (cbInstanceData) { PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); if (!Property) return E_OUTOFMEMORY;
Property->Set = guidPropSet; Property->Id = dwPropID; Property->Flags = KSPROPERTY_TYPE_SET;
CopyMemory((Property+1), pInstanceData, cbInstanceData);
HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); CoTaskMemFree(Property); return hr; } else { KSPROPERTY Property;
Property.Set = guidPropSet; Property.Id = dwPropID; Property.Flags = KSPROPERTY_TYPE_SET;
HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); return hr; }}
HRESULTSTDMETHODCALLTYPECInputPin::Get( REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned){ ULONG BytesReturned;
if (cbInstanceData) { PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); if (!Property) return E_OUTOFMEMORY;
Property->Set = guidPropSet; Property->Id = dwPropID; Property->Flags = KSPROPERTY_TYPE_GET;
CopyMemory((Property+1), pInstanceData, cbInstanceData);
HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); CoTaskMemFree(Property); return hr; } else { KSPROPERTY Property;
Property.Set = guidPropSet; Property.Id = dwPropID; Property.Flags = KSPROPERTY_TYPE_GET;
HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); return hr; }}
HRESULTSTDMETHODCALLTYPECInputPin::QuerySupported( REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport){ KSPROPERTY Property; ULONG BytesReturned;
Property.Set = guidPropSet; Property.Id = dwPropID; Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned);}
//-------------------------------------------------------------------// IKsObject//HANDLESTDMETHODCALLTYPECInputPin::KsGetObjectHandle(){ assert(m_hPin); return m_hPin;}
//-------------------------------------------------------------------// IPin interface//HRESULTSTDMETHODCALLTYPECInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");#endif return NOERROR;}
HRESULTSTDMETHODCALLTYPECInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt){ HRESULT hr;
if (m_Pin) { // already connected return VFW_E_ALREADY_CONNECTED; }
// first check format hr = CheckFormat(pmt); if (FAILED(hr)) { // format is not supported return hr; }
hr = CreatePin(pmt); if (FAILED(hr)) { return hr; }
m_Pin = pConnector; m_Pin->AddRef();
return S_OK;}HRESULTSTDMETHODCALLTYPECInputPin::Disconnect( void){ if (!m_Pin) { // pin was not connected return S_FALSE; }
//FIXME //check if filter is active
m_Pin->Release(); m_Pin = NULL;
#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Disconnect\n");#endif
return S_OK;}HRESULTSTDMETHODCALLTYPECInputPin::ConnectedTo(IPin **pPin){ if (!pPin) return E_POINTER;
if (m_Pin) { // increment reference count m_Pin->AddRef(); *pPin = m_Pin; return S_OK; }
*pPin = NULL; return VFW_E_NOT_CONNECTED;}HRESULTSTDMETHODCALLTYPECInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt){ if (!m_Pin) return VFW_E_NOT_CONNECTED;
#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n");#endif
return E_NOTIMPL;}HRESULTSTDMETHODCALLTYPECInputPin::QueryPinInfo(PIN_INFO *pInfo){ wcscpy(pInfo->achName, m_PinName); pInfo->dir = PINDIR_INPUT; pInfo->pFilter = m_ParentFilter; m_ParentFilter->AddRef();
return S_OK;}HRESULTSTDMETHODCALLTYPECInputPin::QueryDirection(PIN_DIRECTION *pPinDir){ if (pPinDir) { *pPinDir = PINDIR_INPUT; return S_OK; }
return E_POINTER;}HRESULTSTDMETHODCALLTYPECInputPin::QueryId(LPWSTR *Id){ *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR)); if (!*Id) return E_OUTOFMEMORY;
wcscpy(*Id, m_PinName); return S_OK;}
HRESULTSTDMETHODCALLTYPECInputPin::QueryAccept( const AM_MEDIA_TYPE *pmt){ return CheckFormat(pmt);}HRESULTSTDMETHODCALLTYPECInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum){ HRESULT hr; ULONG MediaTypeCount = 0, Index; AM_MEDIA_TYPE * MediaTypes; IKsObject * KsObjectParent; HANDLE hFilter;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) return hr;
hFilter = KsObjectParent->KsGetObjectHandle();
KsObjectParent->Release();
if (!hFilter) return E_HANDLE;
// query media type count hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount); if (FAILED(hr) || !MediaTypeCount) return hr;
// allocate media types MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); if (!MediaTypes) { // not enough memory return E_OUTOFMEMORY; }
// zero media types ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
for(Index = 0; Index < MediaTypeCount; Index++) { // get media type hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId); if (FAILED(hr)) { // failed CoTaskMemFree(MediaTypes); return hr; } }
return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);}
HRESULTSTDMETHODCALLTYPECInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");#endif return E_NOTIMPL;}HRESULTSTDMETHODCALLTYPECInputPin::EndOfStream( void){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");#endif return E_NOTIMPL;}HRESULTSTDMETHODCALLTYPECInputPin::BeginFlush( void){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");#endif return E_NOTIMPL;}HRESULTSTDMETHODCALLTYPECInputPin::EndFlush( void){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");#endif return E_NOTIMPL;}HRESULTSTDMETHODCALLTYPECInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate){#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");#endif return E_NOTIMPL;}
//-------------------------------------------------------------------HRESULTSTDMETHODCALLTYPECInputPin::CheckFormat( const AM_MEDIA_TYPE *pmt){ PKSMULTIPLE_ITEM MultipleItem; PKSDATAFORMAT DataFormat; HRESULT hr; IKsObject * KsObjectParent; HANDLE hFilter;
if (!pmt) return E_POINTER;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) return hr;
hFilter = KsObjectParent->KsGetObjectHandle();
KsObjectParent->Release();
if (!hFilter) return E_HANDLE;
hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem); if (FAILED(hr)) return S_FALSE;
DataFormat = (PKSDATAFORMAT)(MultipleItem + 1); for(ULONG Index = 0; Index < MultipleItem->Count; Index++) { if (IsEqualGUID(pmt->majortype, DataFormat->MajorFormat) && IsEqualGUID(pmt->subtype, DataFormat->SubFormat) && IsEqualGUID(pmt->formattype, DataFormat->Specifier)) { // format is supported CoTaskMemFree(MultipleItem);#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CheckFormat format OK\n");#endif return S_OK; } DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); } //format is not supported CoTaskMemFree(MultipleItem); return S_FALSE;}
HRESULTSTDMETHODCALLTYPECInputPin::CreatePin( const AM_MEDIA_TYPE *pmt){ PKSMULTIPLE_ITEM MediumList; PKSMULTIPLE_ITEM InterfaceList; PKSPIN_MEDIUM Medium; PKSPIN_INTERFACE Interface; IKsInterfaceHandler * InterfaceHandler; HRESULT hr;
// query for pin medium hr = KsQueryMediums(&MediumList); if (FAILED(hr)) return hr;
// query for pin interface hr = KsQueryInterfaces(&InterfaceList); if (FAILED(hr)) { // failed CoTaskMemFree(MediumList); return hr; }
if (MediumList->Count) { //use first available medium Medium = (PKSPIN_MEDIUM)(MediumList + 1); } else { // default to standard medium Medium = &StandardPinMedium; }
if (InterfaceList->Count) { //use first available interface Interface = (PKSPIN_INTERFACE)(InterfaceList + 1); } else { // default to standard interface Interface = &StandardPinInterface; }
if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE) { if (!m_InterfaceHandler) { // now load the IKsInterfaceHandler plugin hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler); if (FAILED(hr)) { // failed to load interface handler plugin#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n");#endif CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList);
return hr; }
// now set the pin hr = InterfaceHandler->KsSetPin((IKsPin*)this); if (FAILED(hr)) { // failed to load interface handler plugin#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");#endif InterfaceHandler->Release(); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); return hr; }
// store interface handler m_InterfaceHandler = InterfaceHandler; }
// now create pin hr = CreatePinHandle(Medium, Interface, pmt); if (FAILED(hr)) { m_InterfaceHandler->Release(); m_InterfaceHandler = InterfaceHandler; } } else {#ifdef KSPROXY_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); OutputDebugStringW(Buffer);#endif hr = E_FAIL; }
// free medium / interface / dataformat CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList);
return hr;}
HRESULTSTDMETHODCALLTYPECInputPin::CreatePinHandle( PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt){ PKSPIN_CONNECT PinConnect; PKSDATAFORMAT DataFormat; ULONG Length; HRESULT hr; IKsObject * KsObjectParent; HANDLE hFilter;
if (!pmt) return E_POINTER;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) return hr;
hFilter = KsObjectParent->KsGetObjectHandle();
KsObjectParent->Release();
if (!hFilter) return E_HANDLE;
if (m_hPin != INVALID_HANDLE_VALUE) { // pin already exists //CloseHandle(m_hPin); //m_hPin = INVALID_HANDLE_VALUE; return S_OK; }
// calc format size Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat;
// allocate pin connect PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length); if (!PinConnect) { // failed return E_OUTOFMEMORY; }
// setup request CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE)); CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM)); PinConnect->PinId = m_PinId; PinConnect->PinToHandle = NULL; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
// get dataformat offset DataFormat = (PKSDATAFORMAT)(PinConnect + 1);
// copy data format DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat; DataFormat->Flags = 0; DataFormat->SampleSize = pmt->lSampleSize; DataFormat->Reserved = 0; CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID)); CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID)); CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID));
if (pmt->cbFormat) { // copy extended format CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat); }
// create pin hr = KsCreatePin(hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
if (SUCCEEDED(hr)) { // store current interface / medium CopyMemory(&m_Medium, Medium, sizeof(KSPIN_MEDIUM)); CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE)); CopyMemory(&m_MediaFormat, pmt, sizeof(AM_MEDIA_TYPE));
#ifdef KSPROXY_TRACE LPOLESTR pMajor, pSub, pFormat; StringFromIID(m_MediaFormat.majortype, &pMajor); StringFromIID(m_MediaFormat.subtype , &pSub); StringFromIID(m_MediaFormat.formattype, &pFormat);
WCHAR Buffer[200]; swprintf(Buffer, L"CInputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor, pSub, pFormat, pmt->pbFormat, pmt->cbFormat); CoTaskMemFree(pMajor); CoTaskMemFree(pSub); CoTaskMemFree(pFormat); OutputDebugStringW(Buffer);#endif
if (pmt->cbFormat) { m_MediaFormat.pbFormat = (BYTE*)CoTaskMemAlloc(pmt->cbFormat); if (!m_MediaFormat.pbFormat) { CoTaskMemFree(PinConnect); m_MediaFormat.pbFormat = NULL; m_MediaFormat.cbFormat = 0; return E_OUTOFMEMORY; } CopyMemory(m_MediaFormat.pbFormat, pmt->pbFormat, pmt->cbFormat); }
LPGUID pGuid; ULONG NumGuids = 0;
// get all supported sets hr = GetSupportedSets(&pGuid, &NumGuids); if (FAILED(hr)) {#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n");#endif return hr; }
// load all proxy plugins hr = LoadProxyPlugins(pGuid, NumGuids); if (FAILED(hr)) {#ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");#endif return hr; }
// free sets CoTaskMemFree(pGuid);
//TODO // connect pin pipes
}
// free pin connect CoTaskMemFree(PinConnect);
return hr;}
HRESULTSTDMETHODCALLTYPECInputPin::GetSupportedSets( LPGUID * pOutGuid, PULONG NumGuids){ KSPROPERTY Property; LPGUID pGuid; ULONG NumProperty = 0; ULONG NumMethods = 0; ULONG NumEvents = 0; ULONG Length; ULONG BytesReturned; HRESULT hr;
Property.Set = GUID_NULL; Property.Id = 0; Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty); KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods); KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents);
Length = NumProperty + NumMethods + NumEvents;
assert(Length);
// allocate guid buffer pGuid = (LPGUID)CoTaskMemAlloc(Length); if (!pGuid) { // failed return E_OUTOFMEMORY; }
NumProperty /= sizeof(GUID); NumMethods /= sizeof(GUID); NumEvents /= sizeof(GUID);
#ifdef KSPROXY_TRACE WCHAR Buffer[200]; swprintf(Buffer, L"CInputPin::GetSupportedSets NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents); OutputDebugStringW(Buffer);#endif
// get all properties hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned); if (FAILED(hr)) { CoTaskMemFree(pGuid); return E_FAIL; } Length -= BytesReturned;
// get all methods if (Length && NumMethods) { hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned); if (FAILED(hr)) { CoTaskMemFree(pGuid); return E_FAIL; } Length -= BytesReturned; }
// get all events if (Length && NumEvents) { hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned); if (FAILED(hr)) { CoTaskMemFree(pGuid); return E_FAIL; } Length -= BytesReturned; }
*pOutGuid = pGuid; *NumGuids = NumProperty+NumEvents+NumMethods; return S_OK;}
HRESULTSTDMETHODCALLTYPECInputPin::LoadProxyPlugins( LPGUID pGuids, ULONG NumGuids){ ULONG Index; LPOLESTR pStr; HKEY hKey, hSubKey; HRESULT hr; IUnknown * pUnknown;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { OutputDebugStringW(L"CInputPin::LoadProxyPlugins failed to open MediaInterfaces key\n"); return E_FAIL; }
// enumerate all sets for(Index = 0; Index < NumGuids; Index++) { // convert to string hr = StringFromCLSID(pGuids[Index], &pStr); if (FAILED(hr)) return E_FAIL;
// now try open class key if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) { // no plugin for that set exists CoTaskMemFree(pStr); continue; }
// try load plugin hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown); if (SUCCEEDED(hr)) { // store plugin m_Plugins.push_back(pUnknown); } // close key RegCloseKey(hSubKey); }
// close media interfaces key RegCloseKey(hKey); return S_OK;}
HRESULTWINAPICInputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication, REFIID riid, LPVOID * ppv){ CInputPin * handler = new CInputPin(ParentFilter, PinName, PinId, Communication);
if (!handler) return E_OUTOFMEMORY;
if (FAILED(handler->QueryInterface(riid, ppv))) { /* not supported */ delete handler; return E_NOINTERFACE; }
return S_OK;}