mirror of
https://github.com/reactos/reactos.git
synced 2025-07-28 11:31:54 +00:00
[KSPROXY]
- Silence traces in IEnumPins interface - Partly implement IKsObject interface for COutputPin - Retrieve pin communication and pass it to constructor of CInputPin - Implement IKsPinEx and IMemInputPin interface for CInputPin - The DVBT network provider can now connect to the BDA Source Filter svn path=/trunk/; revision=45836
This commit is contained in:
parent
eb4f41f03b
commit
57103f1233
6 changed files with 576 additions and 85 deletions
|
@ -64,13 +64,6 @@ CEnumPins::QueryInterface(
|
|||
return NOERROR;
|
||||
}
|
||||
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
LPOLESTR lpstr;
|
||||
StringFromCLSID(refiid, &lpstr);
|
||||
swprintf(Buffer, L"CEnumPins::QueryInterface: NoInterface for %s\n", lpstr);
|
||||
OutputDebugStringW(Buffer);
|
||||
CoTaskMemFree(lpstr);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -89,10 +82,6 @@ CEnumPins::Next(
|
|||
if (cPins > 1 && !pcFetched)
|
||||
return E_INVALIDARG;
|
||||
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
swprintf(Buffer, L"CEnumPins::Next: this %p m_Index %lx cPins %u\n", this, m_Index, cPins);
|
||||
OutputDebugStringW(Buffer);
|
||||
|
||||
while(i < cPins)
|
||||
{
|
||||
if (m_Index + i >= m_Pins.size())
|
||||
|
@ -110,7 +99,6 @@ CEnumPins::Next(
|
|||
}
|
||||
|
||||
m_Index += i;
|
||||
OutputDebugStringW(L"CEnumPins::Next: done\n");
|
||||
if (i < cPins)
|
||||
return S_FALSE;
|
||||
else
|
||||
|
@ -157,14 +145,6 @@ CEnumPins_fnConstructor(
|
|||
{
|
||||
CEnumPins * handler = new CEnumPins(Pins);
|
||||
|
||||
#ifdef MSDVBNP_TRACE
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
LPOLESTR lpstr;
|
||||
StringFromCLSID(riid, &lpstr);
|
||||
swprintf(Buffer, L"CEnumPins_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
|
||||
OutputDebugStringW(Buffer);
|
||||
#endif
|
||||
|
||||
if (!handler)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
|
|
@ -8,13 +8,32 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
|
||||
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
|
||||
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 IKsObject,
|
||||
public IKsPinEx,
|
||||
public IMemInputPin
|
||||
/*
|
||||
public IQualityControl,
|
||||
public IKsPinEx,
|
||||
public IKsPinPipe,
|
||||
public ISpecifyPropertyPages,
|
||||
public IStreamBuilder,
|
||||
|
@ -71,8 +90,36 @@ public:
|
|||
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);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
|
||||
CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId){};
|
||||
HRESULT STDMETHODCALLTYPE CreatePin();
|
||||
HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, PKSDATAFORMAT DataFormat);
|
||||
CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0){};
|
||||
virtual ~CInputPin(){};
|
||||
|
||||
protected:
|
||||
|
@ -82,6 +129,12 @@ protected:
|
|||
HANDLE m_hFilter;
|
||||
HANDLE m_hPin;
|
||||
ULONG m_PinId;
|
||||
IMemAllocator * m_MemAllocator;
|
||||
LONG m_IoCount;
|
||||
KSPIN_COMMUNICATION m_Communication;
|
||||
KSPIN_INTERFACE m_Interface;
|
||||
KSPIN_MEDIUM m_Medium;
|
||||
IPin * m_Pin;
|
||||
};
|
||||
|
||||
HRESULT
|
||||
|
@ -99,12 +152,19 @@ CInputPin::QueryInterface(
|
|||
reinterpret_cast<IUnknown*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
else if (IsEqualGUID(refiid, IID_IMemInputPin))
|
||||
{
|
||||
*Output = (IMemInputPin*)(this);
|
||||
reinterpret_cast<IMemInputPin*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
else if (IsEqualGUID(refiid, IID_IKsObject))
|
||||
{
|
||||
if (!m_hPin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsObject Create PIN!!!\n");
|
||||
DebugBreak();
|
||||
HRESULT hr = CreatePin();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
*Output = (IKsObject*)(this);
|
||||
|
@ -115,8 +175,9 @@ CInputPin::QueryInterface(
|
|||
{
|
||||
if (!m_hPin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsPropertySet Create PIN!!!\n");
|
||||
DebugBreak();
|
||||
HRESULT hr = CreatePin();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
*Output = (IKsPropertySet*)(this);
|
||||
|
@ -127,14 +188,30 @@ CInputPin::QueryInterface(
|
|||
{
|
||||
if (!m_hPin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsControl Create PIN!!!\n");
|
||||
DebugBreak();
|
||||
HRESULT hr = CreatePin();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
*Output = (IKsControl*)(this);
|
||||
reinterpret_cast<IKsControl*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
else if (IsEqualGUID(refiid, IID_IKsPin) ||
|
||||
IsEqualGUID(refiid, IID_IKsPinEx))
|
||||
{
|
||||
if (!m_hPin)
|
||||
{
|
||||
HRESULT hr = CreatePin();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
*Output = (IKsPinEx*)(this);
|
||||
reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
LPOLESTR lpstr;
|
||||
|
@ -146,6 +223,248 @@ CInputPin::QueryInterface(
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IMemInputPin
|
||||
//
|
||||
|
||||
//
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::GetAllocator(IMemAllocator **ppAllocator)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::GetAllocator\n");
|
||||
return VFW_E_NO_ALLOCATOR;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
|
||||
{
|
||||
if (pAllocator)
|
||||
{
|
||||
pAllocator->AddRef();
|
||||
}
|
||||
|
||||
if (m_MemAllocator)
|
||||
{
|
||||
m_MemAllocator->Release();
|
||||
}
|
||||
|
||||
m_MemAllocator = pAllocator;
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::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;
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::Receive(IMediaSample *pSample)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::ReceiveCanBlock( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IKsPin
|
||||
//
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsQueryMediums(
|
||||
PKSMULTIPLE_ITEM* MediumList)
|
||||
{
|
||||
return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsQueryInterfaces(
|
||||
PKSMULTIPLE_ITEM* InterfaceList)
|
||||
{
|
||||
return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsCreateSinkPinHandle(
|
||||
KSPIN_INTERFACE& Interface,
|
||||
KSPIN_MEDIUM& Medium)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::KsCreateSinkPinHandle NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::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;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsPropagateAcquire()
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::KsPropagateAcquire NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsDeliver(
|
||||
IMediaSample* Sample,
|
||||
ULONG Flags)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)
|
||||
{
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
IMemAllocator *
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsPeekAllocator(KSPEEKOPERATION Operation)
|
||||
{
|
||||
if (Operation == KsPeekOperation_AddRef)
|
||||
{
|
||||
// add reference on allocator
|
||||
m_MemAllocator->AddRef();
|
||||
}
|
||||
|
||||
return m_MemAllocator;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator)
|
||||
{
|
||||
if (MemAllocator)
|
||||
{
|
||||
MemAllocator->AddRef();
|
||||
}
|
||||
|
||||
if (m_MemAllocator)
|
||||
{
|
||||
m_MemAllocator->Release();
|
||||
}
|
||||
|
||||
m_MemAllocator = MemAllocator;
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsRenegotiateAllocator()
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
LONG
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsIncrementPendingIoCount()
|
||||
{
|
||||
return InterlockedIncrement((volatile LONG*)&m_IoCount);
|
||||
}
|
||||
|
||||
LONG
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsDecrementPendingIoCount()
|
||||
{
|
||||
return InterlockedDecrement((volatile LONG*)&m_IoCount);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsQualityNotify(
|
||||
ULONG Proportion,
|
||||
REFERENCE_TIME TimeDelta)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IKsPinEx
|
||||
//
|
||||
|
||||
VOID
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::KsNotifyError(
|
||||
IMediaSample* Sample,
|
||||
HRESULT hr)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n");
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IKsPropertySet
|
||||
//
|
||||
|
@ -314,25 +633,36 @@ HRESULT
|
|||
STDMETHODCALLTYPE
|
||||
CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
//MajorFormat: KSDATAFORMAT_TYPE_BDA_ANTENNA
|
||||
//SubType: MEDIASUBTYPE_None
|
||||
//FormatType: FORMAT_None
|
||||
//bFixedSizeSamples 1 bTemporalCompression 0 lSampleSize 1 pUnk 00000000 cbFormat 0 pbFormat 00000000
|
||||
|
||||
//KSPROPSETID_Connection KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT
|
||||
//PriorityClass = KSPRIORITY_NORMAL PrioritySubClass = KSPRIORITY_NORMAL
|
||||
|
||||
|
||||
OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (m_Pin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::ReceiveConnection already connected\n");
|
||||
return VFW_E_ALREADY_CONNECTED;
|
||||
}
|
||||
|
||||
// first check format
|
||||
hr = CheckFormat(pmt);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (FAILED(CheckFormat(pmt)))
|
||||
return hr;
|
||||
|
||||
//FIXME create pin
|
||||
m_Pin = pConnector;
|
||||
m_Pin->AddRef();
|
||||
|
||||
OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
|
@ -345,8 +675,18 @@ HRESULT
|
|||
STDMETHODCALLTYPE
|
||||
CInputPin::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;
|
||||
OutputDebugStringW(L"CInputPin::ConnectedTo NotImplemented\n");
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
}
|
||||
HRESULT
|
||||
|
@ -391,6 +731,56 @@ CInputPin::QueryId(LPWSTR *Id)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::QueryAccept(
|
||||
const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
return CheckFormat(pmt);
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
|
||||
{
|
||||
return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum);
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EndOfStream( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::BeginFlush( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EndFlush( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::CheckFormat(
|
||||
|
@ -452,51 +842,118 @@ CInputPin::CheckFormat(
|
|||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::QueryAccept(
|
||||
const AM_MEDIA_TYPE *pmt)
|
||||
CInputPin::CreatePin()
|
||||
{
|
||||
return CheckFormat(pmt);
|
||||
PKSMULTIPLE_ITEM MediumList;
|
||||
PKSMULTIPLE_ITEM InterfaceList;
|
||||
PKSMULTIPLE_ITEM DataFormatList = NULL;
|
||||
PKSPIN_MEDIUM Medium;
|
||||
PKSDATAFORMAT DataFormat;
|
||||
PKSPIN_INTERFACE Interface;
|
||||
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;
|
||||
}
|
||||
|
||||
// get data ranges
|
||||
hr = KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&DataFormatList);
|
||||
if (FAILED(hr) || DataFormatList->Count == 0)
|
||||
{
|
||||
// failed
|
||||
CoTaskMemFree(MediumList);
|
||||
CoTaskMemFree(InterfaceList);
|
||||
if (DataFormatList)
|
||||
CoTaskMemFree(DataFormatList);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//FIXME determine format
|
||||
// use first available format
|
||||
DataFormat = (PKSDATAFORMAT) (DataFormatList + 1);
|
||||
|
||||
// now create pin
|
||||
hr = CreatePinHandle(Medium, Interface, DataFormat);
|
||||
|
||||
// free medium / interface / dataformat
|
||||
CoTaskMemFree(DataFormatList);
|
||||
CoTaskMemFree(MediumList);
|
||||
CoTaskMemFree(InterfaceList);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
|
||||
CInputPin::CreatePinHandle(
|
||||
PKSPIN_MEDIUM Medium,
|
||||
PKSPIN_INTERFACE Interface,
|
||||
PKSDATAFORMAT DataFormat)
|
||||
{
|
||||
return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum);
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EndOfStream( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::BeginFlush( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::EndFlush( void)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
|
||||
{
|
||||
OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
|
||||
return E_NOTIMPL;
|
||||
PKSPIN_CONNECT PinConnect;
|
||||
ULONG Length;
|
||||
HRESULT hr;
|
||||
|
||||
// calc format size
|
||||
Length = sizeof(KSPIN_CONNECT) + DataFormat->FormatSize;
|
||||
|
||||
// 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;
|
||||
CopyMemory((PinConnect + 1), DataFormat, DataFormat->FormatSize);
|
||||
|
||||
// create pin
|
||||
hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
|
||||
|
||||
// free pin connect
|
||||
CoTaskMemFree(PinConnect);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
@ -506,10 +963,11 @@ CInputPin_Constructor(
|
|||
LPCWSTR PinName,
|
||||
HANDLE hFilter,
|
||||
ULONG PinId,
|
||||
KSPIN_COMMUNICATION Communication,
|
||||
REFIID riid,
|
||||
LPVOID * ppv)
|
||||
{
|
||||
CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId);
|
||||
CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId, Communication);
|
||||
|
||||
if (!handler)
|
||||
return E_OUTOFMEMORY;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<library>setupapi</library>
|
||||
<library>msvcrt</library>
|
||||
<library>strmiids</library>
|
||||
<library>ksuser</library>
|
||||
<group compilerset="gcc">
|
||||
<compilerflag compiler="cxx">-fno-exceptions</compilerflag>
|
||||
<compilerflag compiler="cxx">-fno-rtti</compilerflag>
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
class COutputPin : public IPin
|
||||
class COutputPin : public IPin,
|
||||
public IKsObject
|
||||
/*
|
||||
public IQualityControl,
|
||||
public IKsObject,
|
||||
public IKsPinEx,
|
||||
public IKsPinPipe,
|
||||
public ISpecifyPropertyPages,
|
||||
|
@ -61,6 +61,10 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE EndFlush();
|
||||
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
|
||||
|
||||
//IKsObject methods
|
||||
HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
|
||||
|
||||
|
||||
COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){};
|
||||
virtual ~COutputPin(){};
|
||||
|
||||
|
@ -84,6 +88,12 @@ COutputPin::QueryInterface(
|
|||
reinterpret_cast<IUnknown*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
else if (IsEqualGUID(refiid, IID_IKsObject))
|
||||
{
|
||||
*Output = (IKsObject*)(this);
|
||||
reinterpret_cast<IKsObject*>(*Output)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
LPOLESTR lpstr;
|
||||
|
@ -95,6 +105,20 @@ COutputPin::QueryInterface(
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IKsObject
|
||||
//
|
||||
HANDLE
|
||||
STDMETHODCALLTYPE
|
||||
COutputPin::KsGetObjectHandle()
|
||||
{
|
||||
OutputDebugStringW(L"COutputPin::KsGetObjectHandle CALLED\n");
|
||||
|
||||
//FIXME
|
||||
// return pin handle
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// IPin interface
|
||||
//
|
||||
|
@ -124,6 +148,7 @@ HRESULT
|
|||
STDMETHODCALLTYPE
|
||||
COutputPin::ConnectedTo(IPin **pPin)
|
||||
{
|
||||
*pPin = NULL;
|
||||
OutputDebugStringW(L"COutputPin::ConnectedTo called\n");
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ CInputPin_Constructor(
|
|||
LPCWSTR PinName,
|
||||
HANDLE hFilter,
|
||||
ULONG PinId,
|
||||
KSPIN_COMMUNICATION Communication,
|
||||
REFIID riid,
|
||||
LPVOID * ppv);
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE GetPinInstanceCount(ULONG PinId, PKSPIN_CINSTANCES Instances);
|
||||
HRESULT STDMETHODCALLTYPE GetPinDataflow(ULONG PinId, KSPIN_DATAFLOW * DataFlow);
|
||||
HRESULT STDMETHODCALLTYPE GetPinName(ULONG PinId, KSPIN_DATAFLOW DataFlow, ULONG PinCount, LPWSTR * OutPinName);
|
||||
HRESULT STDMETHODCALLTYPE GetPinCommunication(ULONG PinId, KSPIN_COMMUNICATION * Communication);
|
||||
HRESULT STDMETHODCALLTYPE CreatePins();
|
||||
protected:
|
||||
LONG m_Ref;
|
||||
|
@ -350,6 +351,25 @@ CKsProxy::GetPinInstanceCount(
|
|||
return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Instances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CKsProxy::GetPinCommunication(
|
||||
ULONG PinId,
|
||||
KSPIN_COMMUNICATION * Communication)
|
||||
{
|
||||
KSP_PIN Property;
|
||||
ULONG BytesReturned;
|
||||
|
||||
// setup request
|
||||
Property.Property.Set = KSPROPSETID_Pin;
|
||||
Property.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
||||
Property.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
Property.PinId = PinId;
|
||||
Property.Reserved = 0;
|
||||
|
||||
return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
STDMETHODCALLTYPE
|
||||
CKsProxy::GetPinDataflow(
|
||||
|
@ -446,6 +466,7 @@ CKsProxy::CreatePins()
|
|||
ULONG NumPins, Index;
|
||||
KSPIN_CINSTANCES Instances;
|
||||
KSPIN_DATAFLOW DataFlow;
|
||||
KSPIN_COMMUNICATION Communication;
|
||||
HRESULT hr;
|
||||
WCHAR Buffer[100];
|
||||
LPWSTR PinName;
|
||||
|
@ -465,6 +486,11 @@ CKsProxy::CreatePins()
|
|||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
// query pin communication;
|
||||
hr = GetPinCommunication(Index, &Communication);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
if (Instances.CurrentCount == Instances.PossibleCount)
|
||||
{
|
||||
// already maximum reached for this pin
|
||||
|
@ -487,7 +513,7 @@ CKsProxy::CreatePins()
|
|||
// construct the pins
|
||||
if (DataFlow == KSPIN_DATAFLOW_IN)
|
||||
{
|
||||
hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, IID_IPin, (void**)&pPin);
|
||||
hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, Communication, IID_IPin, (void**)&pPin);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
CoTaskMemFree(PinName);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue