[KSPROXY]

- Recreate resource file with visual studio
- Fix compilation with msvc
- Copy extra format buffer in IEnumMediaTypes::Next
- Create the pin handle in IPin::ReceiveConnection
- Implement IPin::Disconnect for the input pin
- Enumerate media formats and pass it to constructor of CEnumMediaTypes
- Check if the passed format is null in CInputPin::CheckFormat
- Copy extra format buffer after KSDATAFORMAT in the pin connection request
- Implement KsGetMediaType function
- Implement ISpecifyPropertyPages, IKsPropertySet, IKsControl, IStreamBuilder, IKsPinFactory for the output pin
- Implement IPin::ReceiveConnection, IPin::EnumMediaTypes for output pin
- Stub interfaces for IReferenceClock, IMediaSeeking, IKsTopology, IKsAggregateControl, IKsClockPropertySet, ISpecifyPropertyPages, IPersistStream for proxy filter
- Implement IAMDeviceRemoval, IKsControl, IAMFilterMiscFlags, IKsPropertySet interface for proxy filter

svn path=/trunk/; revision=46116
This commit is contained in:
Johannes Anderwald 2010-03-11 21:38:13 +00:00
parent c506f7fd79
commit 718fb52625
10 changed files with 1751 additions and 116 deletions

View file

@ -8,7 +8,9 @@
*/ */
#include "precomp.h" #include "precomp.h"
#ifndef _MSC_VER
const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
#endif
class CKsClockForwarder : public IDistributorNotify, class CKsClockForwarder : public IDistributorNotify,
public IKsObject public IKsObject

View file

@ -9,7 +9,9 @@
#include "precomp.h" #include "precomp.h"
/* FIXME guid mess */ /* FIXME guid mess */
#ifndef _MSC_VER
const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
#endif
const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
class CKsDataTypeHandler : public IKsDataTypeHandler class CKsDataTypeHandler : public IKsDataTypeHandler

View file

@ -103,7 +103,31 @@ CEnumMediaTypes::Next(
if (!MediaType) if (!MediaType)
break; break;
if (m_MediaTypes[m_Index + i].cbFormat)
{
LPBYTE pFormat = (LPBYTE)CoTaskMemAlloc(m_MediaTypes[m_Index + i].cbFormat);
if (!pFormat)
{
CoTaskMemFree(MediaType);
break;
}
CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
MediaType->pbFormat = pFormat;
CopyMemory(MediaType->pbFormat, m_MediaTypes[m_Index + i].pbFormat, m_MediaTypes[m_Index + i].cbFormat);
MediaType->pUnk = (IUnknown *)this;
MediaType->pUnk->AddRef();
}
else
{
CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
}
if (MediaType->pUnk)
{
MediaType->pUnk->AddRef();
}
ppMediaTypes[i] = MediaType; ppMediaTypes[i] = MediaType;
i++; i++;
} }
@ -114,7 +138,6 @@ CEnumMediaTypes::Next(
} }
m_Index += i; m_Index += i;
if (i < cMediaTypes) if (i < cMediaTypes)
return S_FALSE; return S_FALSE;
else else

View file

@ -9,8 +9,12 @@
#include "precomp.h" #include "precomp.h"
const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}}; 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}};
#ifndef _MSC_VER
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
#endif
#ifndef _MSC_VER
KSPIN_INTERFACE StandardPinInterface = KSPIN_INTERFACE StandardPinInterface =
{ {
{STATIC_KSINTERFACESETID_Standard}, {STATIC_KSINTERFACESETID_Standard},
@ -25,6 +29,23 @@ KSPIN_MEDIUM StandardPinMedium =
0 0
}; };
#else
KSPIN_INTERFACE StandardPinInterface =
{
STATIC_KSINTERFACESETID_Standard,
KSINTERFACE_STANDARD_STREAMING,
0
};
KSPIN_MEDIUM StandardPinMedium =
{
STATIC_KSMEDIUMSETID_Standard,
KSMEDIUM_TYPE_ANYINSTANCE,
0
};
#endif
class CInputPin : public IPin, class CInputPin : public IPin,
public IKsPropertySet, public IKsPropertySet,
@ -117,9 +138,9 @@ public:
//--------------------------------------------------------------- //---------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE CreatePin(); HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, PKSDATAFORMAT DataFormat); HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
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){}; 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), m_ReadOnly(0){};
virtual ~CInputPin(){}; virtual ~CInputPin(){};
protected: protected:
@ -135,6 +156,7 @@ protected:
KSPIN_INTERFACE m_Interface; KSPIN_INTERFACE m_Interface;
KSPIN_MEDIUM m_Medium; KSPIN_MEDIUM m_Medium;
IPin * m_Pin; IPin * m_Pin;
BOOL m_ReadOnly;
}; };
HRESULT HRESULT
@ -160,39 +182,18 @@ CInputPin::QueryInterface(
} }
else if (IsEqualGUID(refiid, IID_IKsObject)) else if (IsEqualGUID(refiid, IID_IKsObject))
{ {
if (!m_hPin)
{
HRESULT hr = CreatePin();
if (FAILED(hr))
return hr;
}
*Output = (IKsObject*)(this); *Output = (IKsObject*)(this);
reinterpret_cast<IKsObject*>(*Output)->AddRef(); reinterpret_cast<IKsObject*>(*Output)->AddRef();
return NOERROR; return NOERROR;
} }
else if (IsEqualGUID(refiid, IID_IKsPropertySet)) else if (IsEqualGUID(refiid, IID_IKsPropertySet))
{ {
if (!m_hPin)
{
HRESULT hr = CreatePin();
if (FAILED(hr))
return hr;
}
*Output = (IKsPropertySet*)(this); *Output = (IKsPropertySet*)(this);
reinterpret_cast<IKsPropertySet*>(*Output)->AddRef(); reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
return NOERROR; return NOERROR;
} }
else if (IsEqualGUID(refiid, IID_IKsControl)) else if (IsEqualGUID(refiid, IID_IKsControl))
{ {
if (!m_hPin)
{
HRESULT hr = CreatePin();
if (FAILED(hr))
return hr;
}
*Output = (IKsControl*)(this); *Output = (IKsControl*)(this);
reinterpret_cast<IKsControl*>(*Output)->AddRef(); reinterpret_cast<IKsControl*>(*Output)->AddRef();
return NOERROR; return NOERROR;
@ -200,13 +201,6 @@ CInputPin::QueryInterface(
else if (IsEqualGUID(refiid, IID_IKsPin) || else if (IsEqualGUID(refiid, IID_IKsPin) ||
IsEqualGUID(refiid, IID_IKsPinEx)) IsEqualGUID(refiid, IID_IKsPinEx))
{ {
if (!m_hPin)
{
HRESULT hr = CreatePin();
if (FAILED(hr))
return hr;
}
*Output = (IKsPinEx*)(this); *Output = (IKsPinEx*)(this);
reinterpret_cast<IKsPinEx*>(*Output)->AddRef(); reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
return NOERROR; return NOERROR;
@ -227,7 +221,7 @@ CInputPin::QueryInterface(
// IMemInputPin // IMemInputPin
// //
//
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::GetAllocator(IMemAllocator **ppAllocator) CInputPin::GetAllocator(IMemAllocator **ppAllocator)
@ -251,6 +245,7 @@ CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
} }
m_MemAllocator = pAllocator; m_MemAllocator = pAllocator;
m_ReadOnly = bReadOnly;
return NOERROR; return NOERROR;
} }
@ -466,7 +461,7 @@ CInputPin::KsNotifyError(
//------------------------------------------------------------------- //-------------------------------------------------------------------
// IKsPropertySet // IKsControl
// //
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
@ -477,6 +472,7 @@ CInputPin::KsProperty(
ULONG DataLength, ULONG DataLength,
ULONG* BytesReturned) ULONG* BytesReturned)
{ {
assert(m_hPin != 0);
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
} }
@ -489,6 +485,7 @@ CInputPin::KsMethod(
ULONG DataLength, ULONG DataLength,
ULONG* BytesReturned) ULONG* BytesReturned)
{ {
assert(m_hPin != 0);
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
} }
@ -501,6 +498,8 @@ CInputPin::KsEvent(
ULONG DataLength, ULONG DataLength,
ULONG* BytesReturned) ULONG* BytesReturned)
{ {
assert(m_hPin != 0);
if (EventLength) if (EventLength)
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
else else
@ -619,10 +618,7 @@ HANDLE
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::KsGetObjectHandle() CInputPin::KsGetObjectHandle()
{ {
OutputDebugStringW(L"CInputPin::KsGetObjectHandle CALLED\n"); assert(m_hPin);
//FIXME
// return pin handle
return m_hPin; return m_hPin;
} }
@ -645,7 +641,6 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
if (m_Pin) if (m_Pin)
{ {
OutputDebugStringW(L"CInputPin::ReceiveConnection already connected\n");
return VFW_E_ALREADY_CONNECTED; return VFW_E_ALREADY_CONNECTED;
} }
@ -657,19 +652,36 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
if (FAILED(CheckFormat(pmt))) if (FAILED(CheckFormat(pmt)))
return hr; return hr;
hr = CreatePin(pmt);
if (FAILED(hr))
{
return hr;
}
//FIXME create pin //FIXME create pin
m_Pin = pConnector; m_Pin = pConnector;
m_Pin->AddRef(); m_Pin->AddRef();
OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n");
return S_OK; return S_OK;
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::Disconnect( void) CInputPin::Disconnect( void)
{ {
OutputDebugStringW(L"CInputPin::Disconnect NotImplemented\n"); if (!m_Pin)
return E_NOTIMPL; {
// pin was not connected
return S_FALSE;
}
//FIXME
//check if filter is active
m_Pin->Release();
m_Pin = NULL;
OutputDebugStringW(L"CInputPin::Disconnect\n");
return S_OK;
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
@ -693,6 +705,9 @@ HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
{ {
if (!m_Pin)
return VFW_E_NOT_CONNECTED;
OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n");
return E_NOTIMPL; return E_NOTIMPL;
} }
@ -742,8 +757,41 @@ HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
{ {
return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum); HRESULT hr;
ULONG MediaTypeCount = 0, Index;
AM_MEDIA_TYPE * MediaTypes;
// query media type count
hr = KsGetMediaTypeCount(m_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], m_hFilter, m_PinId);
if (FAILED(hr))
{
// failed
CoTaskMemFree(MediaTypes);
return hr;
}
}
return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
@ -799,6 +847,9 @@ CInputPin::CheckFormat(
Property.PinId = m_PinId; Property.PinId = m_PinId;
Property.Reserved = 0; Property.Reserved = 0;
if (!pmt)
return E_POINTER;
// query for size of dataranges // query for size of dataranges
hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned); hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
@ -842,13 +893,12 @@ CInputPin::CheckFormat(
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
CInputPin::CreatePin() CInputPin::CreatePin(
const AM_MEDIA_TYPE *pmt)
{ {
PKSMULTIPLE_ITEM MediumList; PKSMULTIPLE_ITEM MediumList;
PKSMULTIPLE_ITEM InterfaceList; PKSMULTIPLE_ITEM InterfaceList;
PKSMULTIPLE_ITEM DataFormatList = NULL;
PKSPIN_MEDIUM Medium; PKSPIN_MEDIUM Medium;
PKSDATAFORMAT DataFormat;
PKSPIN_INTERFACE Interface; PKSPIN_INTERFACE Interface;
HRESULT hr; HRESULT hr;
@ -866,19 +916,6 @@ CInputPin::CreatePin()
return hr; 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) if (MediumList->Count)
{ {
//use first available medium //use first available medium
@ -901,15 +938,10 @@ CInputPin::CreatePin()
Interface = &StandardPinInterface; Interface = &StandardPinInterface;
} }
//FIXME determine format
// use first available format
DataFormat = (PKSDATAFORMAT) (DataFormatList + 1);
// now create pin // now create pin
hr = CreatePinHandle(Medium, Interface, DataFormat); hr = CreatePinHandle(Medium, Interface, pmt);
// free medium / interface / dataformat // free medium / interface / dataformat
CoTaskMemFree(DataFormatList);
CoTaskMemFree(MediumList); CoTaskMemFree(MediumList);
CoTaskMemFree(InterfaceList); CoTaskMemFree(InterfaceList);
@ -921,14 +953,15 @@ STDMETHODCALLTYPE
CInputPin::CreatePinHandle( CInputPin::CreatePinHandle(
PKSPIN_MEDIUM Medium, PKSPIN_MEDIUM Medium,
PKSPIN_INTERFACE Interface, PKSPIN_INTERFACE Interface,
PKSDATAFORMAT DataFormat) const AM_MEDIA_TYPE *pmt)
{ {
PKSPIN_CONNECT PinConnect; PKSPIN_CONNECT PinConnect;
PKSDATAFORMAT DataFormat;
ULONG Length; ULONG Length;
HRESULT hr; HRESULT hr;
// calc format size // calc format size
Length = sizeof(KSPIN_CONNECT) + DataFormat->FormatSize; Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat;
// allocate pin connect // allocate pin connect
PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length); PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length);
@ -945,7 +978,24 @@ CInputPin::CreatePinHandle(
PinConnect->PinToHandle = NULL; PinConnect->PinToHandle = NULL;
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
CopyMemory((PinConnect + 1), DataFormat, DataFormat->FormatSize);
// 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 // create pin
hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin); hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin);

View file

@ -10,14 +10,18 @@
#include "precomp.h" #include "precomp.h"
const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard};
const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}}; const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}}; const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};
const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}}; const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
#ifndef _MSC_VER
const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard};
const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
#endif
static INTERFACE_TABLE InterfaceTable[] = static INTERFACE_TABLE InterfaceTable[] =
{ {
{&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor}, {&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor},
@ -258,7 +262,78 @@ KsGetMediaType(
HANDLE FilterHandle, HANDLE FilterHandle,
ULONG PinFactoryId) ULONG PinFactoryId)
{ {
//UNIMPLEMENTED HRESULT hr;
PKSMULTIPLE_ITEM ItemList;
int i = 0;
PKSDATAFORMAT DataFormat;
if (Position < 0)
return E_INVALIDARG;
// get current supported ranges
hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&ItemList);
if (FAILED(hr))
{
// get standard dataranges
hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&ItemList);
//check for success
if (FAILED(hr))
return hr;
}
if ((ULONG)Position >= ItemList->Count)
{
// out of bounds
CoTaskMemFree(ItemList);
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NO_MORE_ITEMS);
}
// goto first datarange
DataFormat = (PKSDATAFORMAT)(ItemList + 1);
while(i != Position)
{
// goto next format;
DataFormat = (PKSDATAFORMAT)(ULONG_PTR)(DataFormat + DataFormat->FormatSize);
i++;
}
DataFormat->FormatSize -= sizeof(KSDATAFORMAT);
if (DataFormat->FormatSize)
{
// copy extra format buffer
AmMediaType->pbFormat = (BYTE*)CoTaskMemAlloc(DataFormat->FormatSize);
if (!AmMediaType->pbFormat)
{
// not enough memory
CoTaskMemFree(ItemList);
return E_OUTOFMEMORY;
}
// copy format buffer
CopyMemory(AmMediaType->pbFormat, (DataFormat + 1), DataFormat->FormatSize);
AmMediaType->cbFormat = DataFormat->FormatSize;
}
else
{
// no format buffer
AmMediaType->pbFormat = NULL;
AmMediaType->cbFormat = 0;
}
// copy type info
CopyMemory(&AmMediaType->majortype, &DataFormat->MajorFormat, sizeof(GUID));
CopyMemory(&AmMediaType->subtype, &DataFormat->SubFormat, sizeof(GUID));
CopyMemory(&AmMediaType->formattype, &DataFormat->Specifier, sizeof(GUID));
AmMediaType->bTemporalCompression = FALSE; //FIXME verify
AmMediaType->pUnk = NULL; //FIXME
AmMediaType->lSampleSize = DataFormat->SampleSize;
AmMediaType->bFixedSizeSamples = (AmMediaType->lSampleSize) ? TRUE : FALSE;
// free dataformat list
CoTaskMemFree(ItemList);
return NOERROR; return NOERROR;
} }

View file

@ -1,9 +1,98 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource."
#define REACTOS_VERSION_DLL #define APSTUDIO_READONLY_SYMBOLS
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS WDM Streaming ActiveMovie Proxy\0" /////////////////////////////////////////////////////////////////////////////
#define REACTOS_STR_INTERNAL_NAME "ksproxy\0" //
#define REACTOS_STR_ORIGINAL_FILENAME "ksproxy.ax\0" // Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include <reactos/reactx.h> /////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Deutsch (Deutschland) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.\0"
END
3 TEXTINCLUDE
BEGIN
"\r\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,3,2600,3264
PRODUCTVERSION 5,3,2600,3264
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040704b0"
BEGIN
VALUE "CompanyName", "ReactOS WDM Streaming ActiveMovie Proxy"
VALUE "FileDescription", "ReactOS WDM Streaming ActiveMovie Proxy"
VALUE "FileVersion", "5, 3, 2600, 3264"
VALUE "InternalName", "ksproxy"
VALUE "LegalCopyright", "Copyright (C) 2010"
VALUE "OriginalFilename", "ksproxy.dll"
VALUE "ProductName", "ReactOS WDM Streaming ActiveMovie Proxy"
VALUE "ProductVersion", "5, 3, 2600, 3264"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x407, 1200
END
END
#endif // Deutsch (Deutschland) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
#include <reactos/version.rc>

View file

@ -8,17 +8,21 @@
*/ */
#include "precomp.h" #include "precomp.h"
#ifndef _MSC_VER
const GUID IID_IKsPinFactory = {0xCD5EBE6BL, 0x8B6E, 0x11D1, {0x8A, 0xE0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
#endif
class COutputPin : public IPin, class COutputPin : public IPin,
public IKsObject public IKsObject,
public IKsPropertySet,
public IStreamBuilder,
public IKsPinFactory,
public ISpecifyPropertyPages,
// public IKsPinPipe,
public IKsControl
/* /*
public IQualityControl, public IQualityControl,
public IKsPinEx, public IKsPinEx,
public IKsPinPipe,
public ISpecifyPropertyPages,
public IStreamBuilder,
public IKsPropertySet,
public IKsPinFactory,
public IKsControl,
public IKsAggregateControl public IKsAggregateControl
public IMediaSeeking, public IMediaSeeking,
public IAMStreamConfig, public IAMStreamConfig,
@ -38,12 +42,25 @@ public:
InterlockedDecrement(&m_Ref); InterlockedDecrement(&m_Ref);
if (!m_Ref) if (!m_Ref)
{ {
delete this; //delete this;
return 0; return 0;
} }
return m_Ref; 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 //IPin methods
HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
@ -61,17 +78,58 @@ public:
HRESULT STDMETHODCALLTYPE EndFlush(); HRESULT STDMETHODCALLTYPE EndFlush();
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
// ISpecifyPropertyPages
HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
//IKsObject methods //IKsObject methods
HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); 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);
COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){}; //IKsControl
virtual ~COutputPin(){}; 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);
//IStreamBuilder
HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph);
HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
//IKsPinFactory
HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId);
virtual ~COutputPin();
protected: protected:
LONG m_Ref; LONG m_Ref;
IBaseFilter * m_ParentFilter; IBaseFilter * m_ParentFilter;
LPCWSTR m_PinName; LPCWSTR m_PinName;
HANDLE m_hPin;
ULONG m_PinId;
IKsObject * m_KsObjectParent;
IPin * m_Pin;
};
COutputPin::~COutputPin()
{
if (m_KsObjectParent)
m_KsObjectParent->Release();
}
COutputPin::COutputPin(
IBaseFilter * ParentFilter,
LPCWSTR PinName,
ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(0), m_PinId(PinId), m_KsObjectParent(0), m_Pin(0)
{
HRESULT hr;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent);
assert(hr == S_OK);
}; };
HRESULT HRESULT
@ -94,6 +152,41 @@ COutputPin::QueryInterface(
reinterpret_cast<IKsObject*>(*Output)->AddRef(); reinterpret_cast<IKsObject*>(*Output)->AddRef();
return NOERROR; return NOERROR;
} }
else if (IsEqualGUID(refiid, IID_IKsPropertySet))
{
*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_IStreamBuilder))
{
*Output = (IStreamBuilder*)(this);
reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPinFactory))
{
*Output = (IKsPinFactory*)(this);
reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
{
*Output = (ISpecifyPropertyPages*)(this);
reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IBaseFilter))
{
OutputDebugStringW(L"COutputPin::QueryInterface query IID_IBaseFilter\n");
DebugBreak();
}
WCHAR Buffer[MAX_PATH]; WCHAR Buffer[MAX_PATH];
LPOLESTR lpstr; LPOLESTR lpstr;
@ -105,6 +198,60 @@ COutputPin::QueryInterface(
return E_NOINTERFACE; return E_NOINTERFACE;
} }
//-------------------------------------------------------------------
// ISpecifyPropertyPages
//
HRESULT
STDMETHODCALLTYPE
COutputPin::GetPages(CAUUID *pPages)
{
OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n");
if (!pPages)
return E_POINTER;
pPages->cElems = 0;
pPages->pElems = NULL;
return S_OK;
}
//-------------------------------------------------------------------
// IKsPinFactory
//
HRESULT
STDMETHODCALLTYPE
COutputPin::KsPinFactory(
ULONG* PinFactory)
{
*PinFactory = m_PinId;
return S_OK;
}
//-------------------------------------------------------------------
// IStreamBuilder
//
HRESULT
STDMETHODCALLTYPE
COutputPin::Render(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
return S_OK;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::Backout(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
return S_OK;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// IKsObject // IKsObject
// //
@ -112,13 +259,161 @@ HANDLE
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::KsGetObjectHandle() COutputPin::KsGetObjectHandle()
{ {
OutputDebugStringW(L"COutputPin::KsGetObjectHandle CALLED\n"); assert(m_hPin);
return m_hPin;
//FIXME
// return pin handle
return NULL;
} }
//-------------------------------------------------------------------
// IKsControl
//
HRESULT
STDMETHODCALLTYPE
COutputPin::KsProperty(
PKSPROPERTY Property,
ULONG PropertyLength,
LPVOID PropertyData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_hPin != 0);
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsMethod(
PKSMETHOD Method,
ULONG MethodLength,
LPVOID MethodData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_hPin != 0);
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsEvent(
PKSEVENT Event,
ULONG EventLength,
LPVOID EventData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_hPin != 0);
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
//
HRESULT
STDMETHODCALLTYPE
COutputPin::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;
}
}
HRESULT
STDMETHODCALLTYPE
COutputPin::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;
}
}
HRESULT
STDMETHODCALLTYPE
COutputPin::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);
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// IPin interface // IPin interface
// //
@ -126,30 +421,92 @@ HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{ {
AM_MEDIA_TYPE MediaType;
HRESULT hr;
HANDLE hFilter;
OutputDebugStringW(L"COutputPin::Connect called\n"); OutputDebugStringW(L"COutputPin::Connect called\n");
return E_NOTIMPL; if (pmt)
{
hr = pReceivePin->QueryAccept(pmt);
if (FAILED(hr))
return hr;
}
else
{
// get parent filter handle
hFilter = m_KsObjectParent->KsGetObjectHandle();
// get media type count
ZeroMemory(&MediaType, sizeof(AM_MEDIA_TYPE));
hr = KsGetMediaType(0, &MediaType, hFilter, m_PinId);
if (FAILED(hr))
return hr;
// query accept
hr = pReceivePin->QueryAccept(&MediaType);
if (FAILED(hr))
return hr;
pmt = &MediaType;
}
//FIXME create pin handle
// receive connection;
hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
if (SUCCEEDED(hr))
{
// increment reference count
pReceivePin->AddRef();
m_Pin = pReceivePin;
OutputDebugStringW(L"COutputPin::Connect success\n");
}
return hr;
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{ {
OutputDebugStringW(L"COutputPin::ReceiveConnection called\n"); return E_UNEXPECTED;
return E_NOTIMPL;
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::Disconnect( void) COutputPin::Disconnect( void)
{ {
OutputDebugStringW(L"COutputPin::Disconnect called\n"); if (!m_Pin)
return E_NOTIMPL; {
// pin was not connected
return S_FALSE;
}
//FIXME
//check if filter is active
m_Pin->Release();
m_Pin = NULL;
OutputDebugStringW(L"COutputPin::Disconnect\n");
return S_OK;
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::ConnectedTo(IPin **pPin) COutputPin::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; *pPin = NULL;
OutputDebugStringW(L"COutputPin::ConnectedTo called\n");
return VFW_E_NOT_CONNECTED; return VFW_E_NOT_CONNECTED;
} }
HRESULT HRESULT
@ -204,8 +561,56 @@ HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
{ {
HRESULT hr;
ULONG MediaTypeCount = 0, Index;
AM_MEDIA_TYPE * MediaTypes;
HANDLE hFilter;
OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n"); OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n");
return E_NOTIMPL;
if (!m_KsObjectParent)
{
// no interface
return E_NOINTERFACE;
}
// get parent filter handle
hFilter = m_KsObjectParent->KsGetObjectHandle();
// query media type count
hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
if (FAILED(hr) || !MediaTypeCount)
{
OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n");
return hr;
}
// allocate media types
MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
if (!MediaTypes)
{
// not enough memory
OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n");
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);
OutputDebugStringW(L"COutputPin::EnumMediaTypes failed2\n");
return hr;
}
}
return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);
} }
HRESULT HRESULT
STDMETHODCALLTYPE STDMETHODCALLTYPE
@ -248,10 +653,11 @@ WINAPI
COutputPin_Constructor( COutputPin_Constructor(
IBaseFilter * ParentFilter, IBaseFilter * ParentFilter,
LPCWSTR PinName, LPCWSTR PinName,
ULONG PinId,
REFIID riid, REFIID riid,
LPVOID * ppv) LPVOID * ppv)
{ {
COutputPin * handler = new COutputPin(ParentFilter, PinName); COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId);
if (!handler) if (!handler)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;

View file

@ -18,6 +18,7 @@
#include <setupapi.h> #include <setupapi.h>
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#include <assert.h>
//#include <debug.h> //#include <debug.h>
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
@ -117,6 +118,7 @@ WINAPI
COutputPin_Constructor( COutputPin_Constructor(
IBaseFilter * ParentFilter, IBaseFilter * ParentFilter,
LPCWSTR PinName, LPCWSTR PinName,
ULONG PinId,
REFIID riid, REFIID riid,
LPVOID * ppv); LPVOID * ppv);
@ -137,4 +139,4 @@ CEnumMediaTypes_fnConstructor(
REFIID riid, REFIID riid,
LPVOID * ppv); LPVOID * ppv);
extern const GUID IID_IKsObject;

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,11 @@
*/ */
#include "precomp.h" #include "precomp.h"
#ifndef _MSC_VER
const GUID KSCATEGORY_QUALITY = {0x97EBAACB, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; const GUID KSCATEGORY_QUALITY = {0x97EBAACB, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
#endif
#define IID_IKsQualityForwarder KSCATEGORY_QUALITY
class CKsQualityForwarder : public IKsQualityForwarder class CKsQualityForwarder : public IKsQualityForwarder
{ {