Author: janderwald Date: Fri Mar 19 16:39:08 2010 New Revision: 46274
URL: http://svn.reactos.org/svn/reactos?rev=46274&view=rev Log: [KSPROXY] - Start implementing IKsAllocator interface - Retrieve the default format for the input and output pin - Instantiate the kernel pin when an interface request for IMemInputPin / IKsPropertySet / IKsObject request arrives - Implement IKsPin::KsCreateSinkPinHandle for the input pin - Partly implement IKsPin::KsPropagateAcquire for input / output pin - Fix asserts in IKsControl::KsProperty, IKsControl::KsMethod, IKsControl::KsEvent - Simplify CInputPin::CheckFormat - Store the currently used pin medium / interface and connection format - Implement IAMBufferNegotiation::SuggestAllocatorProperties, IAMBufferNegotiation::GetAllocatorProperties for the output pin - Pass pin's communication to output pin - Implement IMediaFilter::Pause, IMediaFilter::Run for CKsProxy - CKsProxy is now able to deliver signal statistics for BDA devices (app: SageDvbRecorder, OS: WinXP SP3)
Added: trunk/reactos/dll/directx/ksproxy/allocator.cpp (with props) Modified: trunk/reactos/dll/directx/ksproxy/input_pin.cpp trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild trunk/reactos/dll/directx/ksproxy/output_pin.cpp trunk/reactos/dll/directx/ksproxy/precomp.h trunk/reactos/dll/directx/ksproxy/proxy.cpp
Added: trunk/reactos/dll/directx/ksproxy/allocator.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/allocat... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/allocator.cpp (added) +++ trunk/reactos/dll/directx/ksproxy/allocator.cpp [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -1,0 +1,374 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy + * FILE: dll/directx/ksproxy/allocator.cpp + * PURPOSE: IKsAllocator interface + * + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ +#include "precomp.h" + +const GUID IID_IKsAllocatorEx = {0x091bb63a, 0x603f, 0x11d1, {0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}}; +const GUID IID_IKsAllocator = {0x8da64899, 0xc0d9, 0x11d0, {0x84, 0x13, 0x00, 0x00, 0xf8, 0x22, 0xfe, 0x8a}}; + +class CKsAllocator : public IKsAllocatorEx, + public IMemAllocatorCallbackTemp +{ +public: + 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; + } + //IKsAllocator + HANDLE STDMETHODCALLTYPE KsGetAllocatorHandle(); + KSALLOCATORMODE STDMETHODCALLTYPE KsGetAllocatorMode(); + HRESULT STDMETHODCALLTYPE KsGetAllocatorStatus(PKSSTREAMALLOCATOR_STATUS AllocatorStatus); + VOID STDMETHODCALLTYPE KsSetAllocatorMode(KSALLOCATORMODE Mode); + + //IKsAllocatorEx + PALLOCATOR_PROPERTIES_EX STDMETHODCALLTYPE KsGetProperties(); + VOID STDMETHODCALLTYPE KsSetProperties(PALLOCATOR_PROPERTIES_EX Properties); + VOID STDMETHODCALLTYPE KsSetAllocatorHandle(HANDLE AllocatorHandle); + HANDLE STDMETHODCALLTYPE KsCreateAllocatorAndGetHandle(IKsPin* KsPin); + + //IMemAllocator + HRESULT STDMETHODCALLTYPE SetProperties(ALLOCATOR_PROPERTIES *pRequest, ALLOCATOR_PROPERTIES *pActual); + HRESULT STDMETHODCALLTYPE GetProperties(ALLOCATOR_PROPERTIES *pProps); + HRESULT STDMETHODCALLTYPE Commit(); + HRESULT STDMETHODCALLTYPE Decommit(); + HRESULT STDMETHODCALLTYPE GetBuffer(IMediaSample **ppBuffer, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags); + HRESULT STDMETHODCALLTYPE ReleaseBuffer(IMediaSample *pBuffer); + + //IMemAllocatorCallbackTemp + HRESULT STDMETHODCALLTYPE SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify); + HRESULT STDMETHODCALLTYPE GetFreeCount(LONG *plBuffersFree); + + + CKsAllocator() : m_Ref(0), m_hAllocator(0), m_Mode(KsAllocatorMode_User), m_Notify(0), m_Allocated(0), m_FreeCount(0), m_cbBuffer(0), m_cBuffers(0), m_cbAlign(0), m_cbPrefix(0){} + virtual ~CKsAllocator(){} + +protected: + LONG m_Ref; + HANDLE m_hAllocator; + KSALLOCATORMODE m_Mode; + ALLOCATOR_PROPERTIES_EX m_Properties; + IMemAllocatorNotifyCallbackTemp *m_Notify; + ULONG m_Allocated; + ULONG m_FreeCount; + ULONG m_cbBuffer; + ULONG m_cBuffers; + ULONG m_cbAlign; + ULONG m_cbPrefix; +}; + + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUID(refiid, IID_IUnknown) || + IsEqualGUID(refiid, IID_IKsAllocator) || + IsEqualGUID(refiid, IID_IKsAllocatorEx)) + { + *Output = PVOID(this); + reinterpret_cast<IUnknown*>(*Output)->AddRef(); + return NOERROR; + } + if (IsEqualGUID(refiid, IID_IMemAllocator) || + IsEqualGUID(refiid, IID_IMemAllocatorCallbackTemp)) + { + *Output = (IDistributorNotify*)(this); + reinterpret_cast<IDistributorNotify*>(*Output)->AddRef(); + return NOERROR; + } + + return E_NOINTERFACE; +} + +//------------------------------------------------------------------- +// IMemAllocator +// +HRESULT +STDMETHODCALLTYPE +CKsAllocator::SetProperties( + ALLOCATOR_PROPERTIES *pRequest, + ALLOCATOR_PROPERTIES *pActual) +{ + SYSTEM_INFO SystemInfo; + + OutputDebugStringW(L"CKsAllocator::SetProperties Stub\n"); + + if (!pRequest || !pActual) + return E_POINTER; + + // zero output properties + ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES)); + + // get system info + GetSystemInfo(&SystemInfo); + + if (!pRequest->cbAlign || (pRequest->cbAlign - 1) & SystemInfo.dwAllocationGranularity) + { + // bad alignment + return VFW_E_BADALIGN; + } + + if (m_Mode == KsAllocatorMode_Kernel) + { + // u cannt change a kernel allocator + return VFW_E_ALREADY_COMMITTED; + } + + if (m_Allocated != m_FreeCount) + { + // outstanding buffers + return VFW_E_BUFFERS_OUTSTANDING; + } + + pActual->cbAlign = m_cbAlign = pRequest->cbAlign; + pActual->cbBuffer = m_cbBuffer = pRequest->cbBuffer; + pActual->cbPrefix = m_cbPrefix = pRequest->cbPrefix; + pActual->cBuffers = m_cBuffers = pRequest->cBuffers; + + return NOERROR; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::GetProperties( + ALLOCATOR_PROPERTIES *pProps) +{ + if (!pProps) + return E_POINTER; + + pProps->cbBuffer = m_cbBuffer; + pProps->cBuffers = m_cBuffers; + pProps->cbAlign = m_cbAlign; + pProps->cbPrefix = m_cbPrefix; + + return NOERROR; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::Commit() +{ + if (m_Mode == KsAllocatorMode_Kernel) + { + /* no-op for kernel allocator */ + return NOERROR; + } + + OutputDebugStringW(L"CKsAllocator::Commit NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::Decommit() +{ + if (m_Mode == KsAllocatorMode_Kernel) + { + /* no-op for kernel allocator */ + return NOERROR; + } + + OutputDebugStringW(L"CKsAllocator::Decommit NotImplemented\n"); + return E_NOTIMPL; +} + + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::GetBuffer( + IMediaSample **ppBuffer, + REFERENCE_TIME *pStartTime, + REFERENCE_TIME *pEndTime, + DWORD dwFlags) +{ + OutputDebugStringW(L"CKsAllocator::GetBuffer NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::ReleaseBuffer( + IMediaSample *pBuffer) +{ + OutputDebugStringW(L"CKsAllocator::ReleaseBuffer NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IMemAllocatorCallbackTemp +// +HRESULT +STDMETHODCALLTYPE +CKsAllocator::SetNotify( + IMemAllocatorNotifyCallbackTemp *pNotify) +{ + OutputDebugStringW(L"CKsAllocator::SetNotify\n"); + + if (pNotify) + pNotify->AddRef(); + + if (m_Notify) + m_Notify->Release(); + + m_Notify = pNotify; + return NOERROR; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::GetFreeCount( + LONG *plBuffersFree) +{ + OutputDebugStringW(L"CKsAllocator::GetFreeCount NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IKsAllocator +// +HANDLE +STDMETHODCALLTYPE +CKsAllocator::KsGetAllocatorHandle() +{ + return m_hAllocator; +} + +KSALLOCATORMODE +STDMETHODCALLTYPE +CKsAllocator::KsGetAllocatorMode() +{ + return m_Mode; +} + +HRESULT +STDMETHODCALLTYPE +CKsAllocator::KsGetAllocatorStatus( + PKSSTREAMALLOCATOR_STATUS AllocatorStatus) +{ + return NOERROR; +} +VOID +STDMETHODCALLTYPE +CKsAllocator::KsSetAllocatorMode( + KSALLOCATORMODE Mode) +{ + m_Mode = Mode; +} + +//------------------------------------------------------------------- +// IKsAllocatorEx +// +PALLOCATOR_PROPERTIES_EX +STDMETHODCALLTYPE +CKsAllocator::KsGetProperties() +{ + return &m_Properties; +} + +VOID +STDMETHODCALLTYPE +CKsAllocator::KsSetProperties( + PALLOCATOR_PROPERTIES_EX Properties) +{ + CopyMemory(&m_Properties, Properties, sizeof(ALLOCATOR_PROPERTIES_EX)); +} + +VOID +STDMETHODCALLTYPE +CKsAllocator::KsSetAllocatorHandle( + HANDLE AllocatorHandle) +{ + m_hAllocator = AllocatorHandle; +} + + +HANDLE +STDMETHODCALLTYPE +CKsAllocator::KsCreateAllocatorAndGetHandle( + IKsPin* KsPin) +{ + HRESULT hr; + IKsObject * pObject; + KSALLOCATOR_FRAMING AllocatorFraming; + HANDLE hPin; + + OutputDebugStringW(L"CKsAllocator::KsCreateAllocatorAndGetHandle\n"); + + if (m_hAllocator) + { + CloseHandle(m_hAllocator); + m_hAllocator = NULL; + } + + // get pin IKsObject interface + hr = KsPin->QueryInterface(IID_IKsObject, (void**)&pObject); + if (FAILED(hr)) + return NULL; + + // get pin handle + hPin = pObject->KsGetObjectHandle(); + + //release IKsObject interface + pObject->Release(); + + if (!hPin || hPin == INVALID_HANDLE_VALUE) + return NULL; + + //setup allocator framing + AllocatorFraming.Frames = m_Properties.cBuffers; + AllocatorFraming.FrameSize = m_Properties.cbBuffer; + AllocatorFraming.FileAlignment = (m_Properties.cbAlign -1); + AllocatorFraming.OptionsFlags = KSALLOCATOR_OPTIONF_SYSTEM_MEMORY; + AllocatorFraming.PoolType = (m_Properties.LogicalMemoryType == KS_MemoryTypeKernelPaged); + + DWORD dwError = KsCreateAllocator(hPin, &AllocatorFraming, &m_hAllocator); + if (dwError) + return NULL; + + return m_hAllocator; +} + +HRESULT +WINAPI +CKsAllocator_Constructor( + IUnknown * pUnkOuter, + REFIID riid, + LPVOID * ppv) +{ + OutputDebugStringW(L"CKsAllocator_Constructor\n"); + + CKsAllocator * handler = new CKsAllocator(); + + if (!handler) + return E_OUTOFMEMORY; + + if (FAILED(handler->QueryInterface(riid, ppv))) + { + /* not supported */ + delete handler; + return E_NOINTERFACE; + } + + return NOERROR; +}
Propchange: trunk/reactos/dll/directx/ksproxy/allocator.cpp ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/directx/ksproxy/input_pin.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/input_p... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/input_pin.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/input_pin.cpp [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -185,6 +185,7 @@ 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; @@ -221,6 +222,10 @@ { ZeroMemory(m_FramingProp, sizeof(m_FramingProp)); ZeroMemory(m_FramingEx, sizeof(m_FramingEx)); + + ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE)); + HRESULT hr = KsGetMediaType(0, &m_MediaFormat, m_hFilter, m_PinId); + assert(hr == S_OK); }
HRESULT @@ -229,6 +234,8 @@ IN REFIID refiid, OUT PVOID* Output) { + WCHAR Buffer[100]; + *Output = NULL;
if (IsEqualGUID(refiid, IID_IUnknown) || @@ -240,6 +247,13 @@ } 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; @@ -252,6 +266,13 @@ } 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; @@ -308,7 +329,6 @@ return NOERROR; }
- WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; StringFromCLSID(refiid, &lpstr); swprintf(Buffer, L"CInputPin::QueryInterface: NoInterface for %s\n", lpstr); @@ -578,6 +598,14 @@ STDMETHODCALLTYPE CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) { + WCHAR Buffer[100]; + HRESULT hr; + ALLOCATOR_PROPERTIES Properties; + + hr = pAllocator->GetProperties(&Properties); + 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); + if (pAllocator) { pAllocator->AddRef(); @@ -613,10 +641,15 @@ pProps->cbBuffer = Framing.FrameSize; pProps->cbAlign = Framing.FileAlignment; pProps->cbPrefix = 0; - return hr; } else - return E_NOTIMPL; + hr = E_NOTIMPL; + + 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); + + return hr; }
HRESULT @@ -669,8 +702,7 @@ KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium) { - OutputDebugStringW(L"CInputPin::KsCreateSinkPinHandle NotImplemented\n"); - return E_NOTIMPL; + return CreatePin(&m_MediaFormat); }
HRESULT @@ -707,8 +739,27 @@ STDMETHODCALLTYPE CInputPin::KsPropagateAcquire() { - OutputDebugStringW(L"CInputPin::KsPropagateAcquire NotImplemented\n"); - return E_NOTIMPL; + KSPROPERTY Property; + KSSTATE State; + ULONG BytesReturned; + HRESULT hr; + + OutputDebugStringW(L"CInputPin::KsPropagateAcquire\n"); + + 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; }
HRESULT @@ -744,6 +795,7 @@ STDMETHODCALLTYPE CInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator) { + if (MemAllocator) { MemAllocator->AddRef(); @@ -815,7 +867,7 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); + assert(m_hPin != INVALID_HANDLE_VALUE); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); }
@@ -828,7 +880,7 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); + assert(m_hPin != INVALID_HANDLE_VALUE); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); }
@@ -841,7 +893,7 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); + assert(m_hPin != INVALID_HANDLE_VALUE);
if (EventLength) return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); @@ -1178,60 +1230,33 @@ CInputPin::CheckFormat( const AM_MEDIA_TYPE *pmt) { - KSP_PIN Property; PKSMULTIPLE_ITEM MultipleItem; PKSDATAFORMAT DataFormat; - ULONG BytesReturned; HRESULT hr; - - // prepare request - Property.Property.Set = KSPROPSETID_Pin; - Property.Property.Id = KSPROPERTY_PIN_DATARANGES; - Property.Property.Flags = KSPROPERTY_TYPE_GET; - Property.PinId = m_PinId; - Property.Reserved = 0;
if (!pmt) return E_POINTER;
- // query for size of dataranges - hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned); - - if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA)) - { - // allocate dataranges buffer - MultipleItem = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned); - - if (!MultipleItem) - return E_OUTOFMEMORY; - - // query dataranges - hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); - - if (FAILED(hr)) + hr = KsGetMultiplePinFactoryItems(m_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)) { - // failed to query data ranges + // format is supported CoTaskMemFree(MultipleItem); - return hr; + OutputDebugStringW(L"CInputPin::CheckFormat format OK\n"); + return S_OK; } - - 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); - OutputDebugStringW(L"CInputPin::CheckFormat format OK\n"); - return S_OK; - } - DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); - } - //format is not supported - CoTaskMemFree(MultipleItem); - } + DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); + } + //format is not supported + CoTaskMemFree(MultipleItem); return S_FALSE; }
@@ -1285,32 +1310,35 @@
if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE) { - // now load the IKsInterfaceHandler plugin - hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler); - if (FAILED(hr)) + if (!m_InterfaceHandler) { - // failed to load interface handler plugin - OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n"); - CoTaskMemFree(MediumList); - CoTaskMemFree(InterfaceList); - - return hr; + // 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 + OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n"); + CoTaskMemFree(MediumList); + CoTaskMemFree(InterfaceList); + + return hr; + } + + // now set the pin + hr = InterfaceHandler->KsSetPin((IKsPin*)this); + if (FAILED(hr)) + { + // failed to load interface handler plugin + OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n"); + InterfaceHandler->Release(); + CoTaskMemFree(MediumList); + CoTaskMemFree(InterfaceList); + return hr; + } + + // store interface handler + m_InterfaceHandler = InterfaceHandler; } - - // now set the pin - hr = InterfaceHandler->KsSetPin((IKsPin*)this); - if (FAILED(hr)) - { - // failed to load interface handler plugin - OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n"); - InterfaceHandler->Release(); - CoTaskMemFree(MediumList); - CoTaskMemFree(InterfaceList); - return hr; - } - - // store interface handler - m_InterfaceHandler = InterfaceHandler;
// now create pin hr = CreatePinHandle(Medium, Interface, pmt); @@ -1320,6 +1348,14 @@ m_InterfaceHandler = InterfaceHandler; } } + else + { + WCHAR Buffer[100]; + swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); + OutputDebugStringW(Buffer); + DebugBreak(); + hr = E_FAIL; + }
// free medium / interface / dataformat CoTaskMemFree(MediumList); @@ -1339,6 +1375,15 @@ PKSDATAFORMAT DataFormat; ULONG Length; HRESULT hr; + + 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; @@ -1379,6 +1424,42 @@
// create pin hr = KsCreatePin(m_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)); + + 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); + + 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); + } + + //TODO + // connect pin pipes + + }
// free pin connect CoTaskMemFree(PinConnect);
Modified: trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/ksproxy... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -20,7 +20,7 @@ <group compilerset="msc"> <compilerflag compiler="cxx">/GR-</compilerflag> </group> - + <file>allocator.cpp</file> <file>basicaudio.cpp</file> <file>classfactory.cpp</file> <file>clockforward.cpp</file>
Modified: trunk/reactos/dll/directx/ksproxy/output_pin.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/output_... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/output_pin.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/output_pin.cpp [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -154,8 +154,12 @@ //IMemAllocatorNotifyCallbackTemp HRESULT STDMETHODCALLTYPE NotifyRelease();
- COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId); + //--------------------------------------------------------------- + COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication); virtual ~COutputPin(); + 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);
protected: LONG m_Ref; @@ -178,7 +182,11 @@ KSPIN_COMMUNICATION m_Communication; KSPIN_INTERFACE m_Interface; KSPIN_MEDIUM m_Medium; + AM_MEDIA_TYPE m_MediaFormat; + IMediaSeeking * m_FilterMediaSeeking; + ALLOCATOR_PROPERTIES m_Properties; + IKsInterfaceHandler * m_InterfaceHandler; };
COutputPin::~COutputPin() @@ -190,21 +198,23 @@ COutputPin::COutputPin( IBaseFilter * ParentFilter, LPCWSTR PinName, - ULONG PinId) : m_Ref(0), - m_ParentFilter(ParentFilter), - m_PinName(PinName), - m_hPin(INVALID_HANDLE_VALUE), - m_PinId(PinId), - m_KsObjectParent(0), - m_Pin(0), - m_KsAllocatorEx(0), - m_PipeAllocatorFlag(0), - m_bPinBusCacheInitialized(0), - m_FilterName(0), - m_MemAllocator(0), - m_IoCount(0), - m_Communication(KSPIN_COMMUNICATION_NONE), - m_FilterMediaSeeking(0) + ULONG PinId, + KSPIN_COMMUNICATION Communication) : m_Ref(0), + m_ParentFilter(ParentFilter), + m_PinName(PinName), + m_hPin(INVALID_HANDLE_VALUE), + m_PinId(PinId), + m_KsObjectParent(0), + m_Pin(0), + m_KsAllocatorEx(0), + m_PipeAllocatorFlag(0), + m_bPinBusCacheInitialized(0), + m_FilterName(0), + m_MemAllocator(0), + m_IoCount(0), + m_Communication(Communication), + m_FilterMediaSeeking(0), + m_InterfaceHandler(0) { HRESULT hr;
@@ -216,6 +226,9 @@
ZeroMemory(m_FramingProp, sizeof(m_FramingProp)); ZeroMemory(m_FramingEx, sizeof(m_FramingEx)); + + hr = KsGetMediaType(0, &m_MediaFormat, m_KsObjectParent->KsGetObjectHandle(), m_PinId); + assert(hr == S_OK); };
HRESULT @@ -235,6 +248,13 @@ } else if (IsEqualGUID(refiid, IID_IKsObject)) { + if (m_hPin == INVALID_HANDLE_VALUE) + { + HRESULT hr = CreatePin(&m_MediaFormat); + if (FAILED(hr)) + return hr; + } + OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsObject\n"); *Output = (IKsObject*)(this); reinterpret_cast<IKsObject*>(*Output)->AddRef(); @@ -266,8 +286,13 @@ } else if (IsEqualGUID(refiid, IID_IKsPropertySet)) { + if (m_hPin == INVALID_HANDLE_VALUE) + { + HRESULT hr = CreatePin(&m_MediaFormat); + if (FAILED(hr)) + return hr; + } OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPropertySet\n"); - DebugBreak(); *Output = (IKsPropertySet*)(this); reinterpret_cast<IKsPropertySet*>(*Output)->AddRef(); return NOERROR; @@ -329,7 +354,7 @@ WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; StringFromCLSID(refiid, &lpstr); - swprintf(Buffer, L"COutputPin::QueryInterface: NoInterface for %s\n", lpstr); + swprintf(Buffer, L"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr, m_PinId, m_PinName); OutputDebugStringW(Buffer); CoTaskMemFree(lpstr);
@@ -344,8 +369,16 @@ COutputPin::SuggestAllocatorProperties( const ALLOCATOR_PROPERTIES *pprop) { - OutputDebugStringW(L"COutputPin::SuggestAllocatorProperties NotImplemented\n"); - return E_NOTIMPL; + OutputDebugStringW(L"COutputPin::SuggestAllocatorProperties\n"); + + if (m_Pin) + { + // pin is already connected + return VFW_E_ALREADY_CONNECTED; + } + + CopyMemory(&m_Properties, pprop, sizeof(ALLOCATOR_PROPERTIES)); + return NOERROR; }
HRESULT @@ -353,8 +386,22 @@ COutputPin::GetAllocatorProperties( ALLOCATOR_PROPERTIES *pprop) { - OutputDebugStringW(L"COutputPin::GetAllocatorProperties NotImplemented\n"); - return E_NOTIMPL; + OutputDebugStringW(L"COutputPin::GetAllocatorProperties\n"); + + if (!m_Pin) + { + // you should call this method AFTER you connected + return E_UNEXPECTED; + } + + if (!m_KsAllocatorEx) + { + // something went wrong while creating the allocator + return E_FAIL; + } + + CopyMemory(pprop, &m_Properties, sizeof(ALLOCATOR_PROPERTIES)); + return NOERROR; }
//------------------------------------------------------------------- @@ -669,8 +716,27 @@ STDMETHODCALLTYPE COutputPin::KsPropagateAcquire() { - OutputDebugStringW(L"COutputPin::KsPropagateAcquire NotImplemented\n"); - return E_NOTIMPL; + KSPROPERTY Property; + KSSTATE State; + ULONG BytesReturned; + HRESULT hr; + + OutputDebugStringW(L"COutputPin::KsPropagateAcquire\n"); + + 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; }
HRESULT @@ -975,7 +1041,7 @@ COutputPin::KsGetObjectHandle() { OutputDebugStringW(L"COutputPin::KsGetObjectHandle\n"); - assert(m_hPin); + assert(m_hPin != INVALID_HANDLE_VALUE); return m_hPin; }
@@ -991,9 +1057,19 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); - OutputDebugStringW(L"COutputPin::KsProperty\n"); - return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); + HRESULT hr; + WCHAR Buffer[100]; + LPOLESTR pstr; + + assert(m_hPin != INVALID_HANDLE_VALUE); + + hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); + + StringFromCLSID(Property->Set, &pstr); + swprintf(Buffer, L"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr, Property->Id, Property->Flags, hr); + OutputDebugStringW(Buffer); + + return hr; }
HRESULT @@ -1005,7 +1081,7 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); + assert(m_hPin != INVALID_HANDLE_VALUE); OutputDebugStringW(L"COutputPin::KsMethod\n"); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); } @@ -1019,7 +1095,7 @@ ULONG DataLength, ULONG* BytesReturned) { - assert(m_hPin != 0); + assert(m_hPin != INVALID_HANDLE_VALUE);
OutputDebugStringW(L"COutputPin::KsEvent\n");
@@ -1044,8 +1120,6 @@ DWORD cbPropData) { ULONG BytesReturned; - - OutputDebugStringW(L"COutputPin::Set\n");
if (cbInstanceData) { @@ -1089,8 +1163,6 @@ { ULONG BytesReturned;
- OutputDebugStringW(L"COutputPin::Get\n"); - if (cbInstanceData) { PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); @@ -1160,21 +1232,12 @@ } 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); + // query accept + hr = pReceivePin->QueryAccept(&m_MediaFormat); if (FAILED(hr)) return hr;
- // query accept - hr = pReceivePin->QueryAccept(&MediaType); - if (FAILED(hr)) - return hr; - - pmt = &MediaType; + pmt = &m_MediaFormat; }
//FIXME create pin handle @@ -1385,16 +1448,265 @@ return E_NOTIMPL; }
+//------------------------------------------------------------------- +HRESULT +STDMETHODCALLTYPE +COutputPin::CheckFormat( + const AM_MEDIA_TYPE *pmt) +{ + PKSMULTIPLE_ITEM MultipleItem; + PKSDATAFORMAT DataFormat; + HRESULT hr; + + if (!pmt) + return E_POINTER; + + HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle(); + assert(hFilter != NULL); + + 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); + OutputDebugStringW(L"COutputPin::CheckFormat format OK\n"); + return S_OK; + } + DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); + } + //format is not supported + CoTaskMemFree(MultipleItem); + return S_FALSE; +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::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) + { + // now create pin + hr = CreatePinHandle(Medium, Interface, pmt); + if (FAILED(hr)) + { + m_InterfaceHandler->Release(); + m_InterfaceHandler = InterfaceHandler; + } + + 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 + OutputDebugStringW(L"COutputPin::CreatePin failed to load InterfaceHandlerPlugin\n"); + CoTaskMemFree(MediumList); + CoTaskMemFree(InterfaceList); + + return hr; + } + + // now set the pin + hr = InterfaceHandler->KsSetPin((IKsPin*)this); + if (FAILED(hr)) + { + // failed to load interface handler plugin + OutputDebugStringW(L"COutputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n"); + InterfaceHandler->Release(); + CoTaskMemFree(MediumList); + CoTaskMemFree(InterfaceList); + return hr; + } + + // store interface handler + m_InterfaceHandler = InterfaceHandler; + } + } + else + { + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); + OutputDebugStringW(Buffer); + DebugBreak(); + hr = E_FAIL; + } + + // free medium / interface / dataformat + CoTaskMemFree(MediumList); + CoTaskMemFree(InterfaceList); + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::CreatePinHandle( + PKSPIN_MEDIUM Medium, + PKSPIN_INTERFACE Interface, + const AM_MEDIA_TYPE *pmt) +{ + PKSPIN_CONNECT PinConnect; + PKSDATAFORMAT DataFormat; + ULONG Length; + HRESULT hr; + + 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); + } + + HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle(); + assert(hFilter != NULL); + + // 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)); + + 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"COutputPin::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); + + 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); + } + + //TODO + // connect pin pipes + + } + // free pin connect + CoTaskMemFree(PinConnect); + + return hr; +} + HRESULT WINAPI COutputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, + KSPIN_COMMUNICATION Communication, REFIID riid, LPVOID * ppv) { - COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId); + COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId, Communication);
if (!handler) return E_OUTOFMEMORY;
Modified: trunk/reactos/dll/directx/ksproxy/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/precomp... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/precomp.h [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/precomp.h [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -134,6 +134,7 @@ IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, + KSPIN_COMMUNICATION Communication, REFIID riid, LPVOID * ppv);
@@ -170,3 +171,5 @@ extern const GUID IID_IKsAggregateControl; extern const GUID IID_IKsPinPipe; extern const GUID IID_IKsPinFactory; +extern KSPIN_INTERFACE StandardPinInterface; +extern KSPIN_MEDIUM StandardPinMedium;
Modified: trunk/reactos/dll/directx/ksproxy/proxy.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/proxy.c... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/proxy.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/proxy.cpp [iso-8859-1] Fri Mar 19 16:39:08 2010 @@ -171,7 +171,7 @@ HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
- CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0), m_hClock(0) {}; + CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock((IReferenceClock*)this), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0), m_hClock(0) {}; ~CKsProxy() { if (m_hDevice) @@ -189,6 +189,9 @@ HRESULT STDMETHODCALLTYPE GetMediaSeekingFormats(PKSMULTIPLE_ITEM *FormatList); HRESULT STDMETHODCALLTYPE CreateClockInstance(); HRESULT STDMETHODCALLTYPE PerformClockProperty(ULONG PropertyId, ULONG PropertyFlags, PVOID OutputBuffer, ULONG OutputBufferSize); + HRESULT STDMETHODCALLTYPE SetPinState(KSSTATE State); + + protected: LONG m_Ref; IFilterGraph *m_pGraph; @@ -1581,6 +1584,7 @@ HRESULT hr; PIN_DIRECTION PinDirection; KSPIN_COMMUNICATION Communication; + WCHAR Buffer[100];
for(Index = 0; Index < m_Pins.size(); Index++) { @@ -1604,7 +1608,8 @@ } }
- OutputDebugStringW(L"CKsProxy::GetMiscFlags stub\n"); + swprintf(Buffer, L"CKsProxy::GetMiscFlags stub Flags %x\n", Flags); + OutputDebugStringW(Buffer); return Flags; }
@@ -2373,7 +2378,7 @@ } else { - hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, IID_IPin, (void**)&pPin); + hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, Communication, IID_IPin, (void**)&pPin); if (FAILED(hr)) { CoTaskMemFree(PinName); @@ -2519,8 +2524,21 @@ STDMETHODCALLTYPE CKsProxy::Pause() { - OutputDebugStringW(L"CKsProxy::Pause : NotImplemented\n"); - return E_NOTIMPL; + HRESULT hr = S_OK; + + OutputDebugStringW(L"CKsProxy::Pause\n"); + + if (m_FilterState == State_Stopped) + { + hr = SetPinState(KSSTATE_PAUSE); + if (FAILED(hr)) + return hr; + + } + + m_FilterState = State_Paused; + return hr; + }
HRESULT @@ -2528,8 +2546,82 @@ CKsProxy::Run( REFERENCE_TIME tStart) { - OutputDebugStringW(L"CKsProxy::Run : NotImplemented\n"); - return E_NOTIMPL; + HRESULT hr; + + OutputDebugStringW(L"CKsProxy::Run\n"); + + if (m_FilterState == State_Stopped) + { + // setting filter state to pause + hr = Pause(); + if (FAILED(hr)) + return hr; + + assert(m_FilterState == State_Paused); + } + + hr = SetPinState(KSSTATE_RUN); + if (FAILED(hr)) + return hr; + + m_FilterState = State_Running; + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetPinState( + KSSTATE State) +{ + HRESULT hr = S_OK; + ULONG Index; + IKsObject *pObject; + ULONG BytesReturned; + KSPROPERTY Property; + + Property.Set = KSPROPSETID_Connection; + Property.Id = KSPROPERTY_CONNECTION_STATE; + Property.Flags = KSPROPERTY_TYPE_SET; + + // set all pins to running state + for(Index = 0; Index < m_Pins.size(); Index++) + { + IPin * Pin = m_Pins[Index]; + if (!Pin) + continue; + + //check if the pin is connected + IPin * TempPin; + hr = Pin->ConnectedTo(&TempPin); + if (FAILED(hr)) + { + // skip unconnected pins + continue; + } + + // release connected pin + TempPin->Release(); + + //query IKsObject interface + hr = Pin->QueryInterface(IID_IKsObject, (void**)&pObject); + + // get pin handle + HANDLE hPin = pObject->KsGetObjectHandle(); + + // sanity check + assert(hPin && hPin != INVALID_HANDLE_VALUE); + + // now set state + hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned); + + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::SetPinState Index %u State %u hr %lx\n", Index, State, hr); + OutputDebugStringW(Buffer); + + if (FAILED(hr)) + return hr; + } + return hr; }
HRESULT @@ -2563,21 +2655,29 @@ // FIXME // need locks
- if (!pClock) - return E_POINTER; - - hr = pClock->QueryInterface(IID_IKsClock, (void**)&pKsClock); - if (FAILED(hr)) - return hr; - - // get clock handle - hClock = pKsClock->KsGetClockHandle(); - if (!hClock || hClock == INVALID_HANDLE_VALUE) - { - // failed + if (pClock) + { + hr = pClock->QueryInterface(IID_IKsClock, (void**)&pKsClock); + if (FAILED(hr)) + { + hr = m_ReferenceClock->QueryInterface(IID_IKsClock, (void**)&pKsClock); + if (FAILED(hr)) + return hr; + } + + // get clock handle + hClock = pKsClock->KsGetClockHandle(); + + // release IKsClock interface pKsClock->Release(); - return E_FAIL; - } + m_hClock = hClock; + } + else + { + // no clock handle + m_hClock = NULL; + } +
// distribute clock to all pins for(Index = 0; Index < m_Pins.size(); Index++) @@ -2601,7 +2701,7 @@ Property.Flags = KSPROPERTY_TYPE_SET;
// set master clock - hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)hClock, sizeof(HANDLE), &BytesReturned); + hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&m_hClock, sizeof(HANDLE), &BytesReturned);
if (FAILED(hr)) { @@ -2609,8 +2709,10 @@ hr != MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND)) { // failed to set master clock - pKsClock->Release(); pObject->Release(); + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::SetSyncSource KSPROPERTY_STREAM_MASTERCLOCK failed with %lx\n", hr); + OutputDebugStringW(Buffer); return hr; } } @@ -2642,6 +2744,7 @@ }
m_ReferenceClock = pClock; + OutputDebugStringW(L"CKsProxy::SetSyncSource done\n"); return S_OK; }