Author: janderwald
Date: Sat Mar 13 18:36:30 2010
New Revision: 46176
URL:
http://svn.reactos.org/svn/reactos?rev=46176&view=rev
Log:
[PSDK]
- Fix KSPROPSETID_Stream definition
[KSPROXY]
- Implement IKsClockPropertySet, IReferenceClock, IMediaSeeking, IKsTopology interface for
CKsProxy
- Implement more of IBaseFilter::SetSyncSource for CKsProxy
- Add missing AddRef to IBaseFilter::QueryFilterInfo for CKsProxy
Added:
trunk/reactos/dll/directx/ksproxy/node.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
trunk/reactos/include/psdk/ks.h
Modified: trunk/reactos/dll/directx/ksproxy/input_pin.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/input_…
==============================================================================
--- trunk/reactos/dll/directx/ksproxy/input_pin.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/ksproxy/input_pin.cpp [iso-8859-1] Sat Mar 13 18:36:30 2010
@@ -140,7 +140,7 @@
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);
- 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){};
+ 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(INVALID_HANDLE_VALUE), m_PinId(PinId),
m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0),
m_ReadOnly(0){};
virtual ~CInputPin(){};
protected:
Modified: trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/ksprox…
==============================================================================
--- trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/ksproxy/ksproxy.rbuild [iso-8859-1] Sat Mar 13 18:36:30
2010
@@ -33,6 +33,7 @@
<file>interface.cpp</file>
<file>ksproxy.cpp</file>
<file>ksproxy.rc</file>
+ <file>node.cpp</file>
<file>output_pin.cpp</file>
<file>proxy.cpp</file>
<file>qualityforward.cpp</file>
Added: trunk/reactos/dll/directx/ksproxy/node.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/node.c…
==============================================================================
--- trunk/reactos/dll/directx/ksproxy/node.cpp (added)
+++ trunk/reactos/dll/directx/ksproxy/node.cpp [iso-8859-1] Sat Mar 13 18:36:30 2010
@@ -1,0 +1,157 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
+ * FILE: dll/directx/ksproxy/node.cpp
+ * PURPOSE: Control Node
+ *
+ * PROGRAMMERS: Johannes Anderwald (janderwald(a)reactos.org)
+ */
+#include "precomp.h"
+
+class CKsNode : public IKsControl
+{
+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;
+ }
+
+ //IKsControl
+ HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength,
LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
+ HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID
MethodData, ULONG DataLength, ULONG* BytesReturned);
+ HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID
EventData, ULONG DataLength, ULONG* BytesReturned);
+
+ CKsNode(IUnknown * pUnkOuter, HANDLE Handle) : m_Ref(0), m_pUnkOuter(pUnkOuter),
m_Handle(Handle){};
+ virtual ~CKsNode()
+ {
+ CloseHandle(m_Handle);
+ };
+
+protected:
+ LONG m_Ref;
+ IUnknown * m_pUnkOuter;
+ HANDLE m_Handle;
+};
+
+HRESULT
+STDMETHODCALLTYPE
+CKsNode::QueryInterface(
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ if (IsEqualGUID(refiid, IID_IUnknown) ||
+ IsEqualGUID(refiid, IID_IKsControl))
+ {
+ *Output = PVOID(this);
+ reinterpret_cast<IUnknown*>(*Output)->AddRef();
+ return NOERROR;
+ }
+
+ return E_NOINTERFACE;
+}
+
+//-------------------------------------------------------------------
+// IKsControl
+//
+HRESULT
+STDMETHODCALLTYPE
+CKsNode::KsProperty(
+ PKSPROPERTY Property,
+ ULONG PropertyLength,
+ LPVOID PropertyData,
+ ULONG DataLength,
+ ULONG* BytesReturned)
+{
+ assert(m_Handle != 0);
+ return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)Property,
PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CKsNode::KsMethod(
+ PKSMETHOD Method,
+ ULONG MethodLength,
+ LPVOID MethodData,
+ ULONG DataLength,
+ ULONG* BytesReturned)
+{
+ assert(m_Handle != 0);
+ return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)Method,
MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CKsNode::KsEvent(
+ PKSEVENT Event,
+ ULONG EventLength,
+ LPVOID EventData,
+ ULONG DataLength,
+ ULONG* BytesReturned)
+{
+ assert(m_Handle != 0);
+
+ if (EventLength)
+ return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_ENABLE_EVENT, (PVOID)Event,
EventLength, (PVOID)EventData, DataLength, BytesReturned);
+ else
+ return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_DISABLE_EVENT, (PVOID)Event,
EventLength, NULL, 0, BytesReturned);
+}
+
+HRESULT
+WINAPI
+CKsNode_Constructor(
+ IUnknown * pUnkOuter,
+ HANDLE ParentHandle,
+ ULONG NodeId,
+ ACCESS_MASK DesiredAccess,
+ REFIID riid,
+ LPVOID * ppv)
+{
+ HRESULT hr;
+ HANDLE handle;
+ KSNODE_CREATE NodeCreate;
+
+ OutputDebugStringW(L"CKsNode_Constructor\n");
+
+ //setup request
+ NodeCreate.CreateFlags = 0;
+ NodeCreate.Node = NodeId;
+
+ hr = KsCreateTopologyNode(ParentHandle, &NodeCreate, DesiredAccess,
&handle);
+ if (hr != NOERROR)
+ {
+ OutputDebugString("CKsNode_Constructor failed to open device\n");
+ return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, hr);
+ }
+
+ CKsNode * quality = new CKsNode(pUnkOuter, handle);
+
+ if (!quality)
+ {
+ // free clock handle
+ CloseHandle(handle);
+ return E_OUTOFMEMORY;
+ }
+
+ if (FAILED(quality->QueryInterface(riid, ppv)))
+ {
+ /* not supported */
+ delete quality;
+ return E_NOINTERFACE;
+ }
+
+ return NOERROR;
+}
Propchange: trunk/reactos/dll/directx/ksproxy/node.cpp
------------------------------------------------------------------------------
svn:eol-style = native
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] Sat Mar 13 18:36:30
2010
@@ -123,7 +123,7 @@
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)
+ 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)
{
HRESULT hr;
Modified: trunk/reactos/dll/directx/ksproxy/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/precom…
==============================================================================
--- trunk/reactos/dll/directx/ksproxy/precomp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/ksproxy/precomp.h [iso-8859-1] Sat Mar 13 18:36:30 2010
@@ -20,6 +20,20 @@
#include <vector>
#include <assert.h>
//#include <debug.h>
+
+
+interface DECLSPEC_UUID("877E4351-6FEA-11D0-B863-00AA00A216A1") IKsClock;
+
+#undef INTERFACE
+#define INTERFACE IKsClock
+
+DECLARE_INTERFACE_(IKsClock, IUnknown)
+{
+ STDMETHOD_(HANDLE, KsGetClockHandle)(
+ THIS
+ ) PURE;
+};
+
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID*
ppvObject);
@@ -139,4 +153,15 @@
REFIID riid,
LPVOID * ppv);
+/* node.cpp */
+HRESULT
+WINAPI
+CKsNode_Constructor(
+ IUnknown * pUnkOuter,
+ HANDLE ParentHandle,
+ ULONG NodeId,
+ ACCESS_MASK DesiredAccess,
+ REFIID riid,
+ LPVOID * ppv);
+
extern const GUID IID_IKsObject;
Modified: trunk/reactos/dll/directx/ksproxy/proxy.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/proxy.…
==============================================================================
--- trunk/reactos/dll/directx/ksproxy/proxy.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/ksproxy/proxy.cpp [iso-8859-1] Sat Mar 13 18:36:30 2010
@@ -14,13 +14,16 @@
const GUID IID_ISpecifyPropertyPages = {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00,
0xAA, 0x00, 0x34, 0x1D, 0x07}};
const GUID IID_IPersistStream = {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x46}};
const GUID KSPROPSETID_MediaSeeking = {0xEE904F0CL, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00,
0xA0, 0xC9, 0x22, 0x31, 0x96}};
+const GUID KSPROPSETID_Clock = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB,
0x04, 0xC1, 0x00, 0x00}};
+const GUID KSEVENTSETID_Clock = {0x364D8E20L, 0x62C7, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB,
0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Stream = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20,
0xaf, 0xd1, 0x56, 0xe4}};
#endif
const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0,
0x4F, 0x79, 0x71, 0xE0}};
const GUID IID_IKsAggregateControl = {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00,
0xA0, 0xC9, 0x22, 0x31, 0x96}};
const GUID IID_IKsClockPropertySet = {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00,
0xA0, 0xC9, 0x22, 0x31, 0x96}};
const GUID IID_IKsTopology = {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00,
0xA0, 0xC9, 0x22, 0x31, 0x96}};
-
+const GUID IID_IKsClock = {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00,
0xAA, 0x00, 0xA2, 0x16, 0xA1}};
/*
Needs IKsClock, IKsNotifyEvent
*/
@@ -35,6 +38,7 @@
public IReferenceClock,
public IMediaSeeking,
public IKsPropertySet,
+ public IKsClock,
public IKsClockPropertySet,
public IAMFilterMiscFlags,
public IKsControl,
@@ -148,6 +152,9 @@
// IKsObject
HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
+ // IKsClock
+ HANDLE STDMETHODCALLTYPE KsGetClockHandle();
+
//IAMDeviceRemoval
HRESULT STDMETHODCALLTYPE DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR
*pwszSymbolicLink);
HRESULT STDMETHODCALLTYPE Reassociate(void);
@@ -163,7 +170,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) {};
+ 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()
{
if (m_hDevice)
@@ -178,6 +185,9 @@
HRESULT STDMETHODCALLTYPE GetPinName(ULONG PinId, KSPIN_DATAFLOW DataFlow, ULONG
PinCount, LPWSTR * OutPinName);
HRESULT STDMETHODCALLTYPE GetPinCommunication(ULONG PinId, KSPIN_COMMUNICATION *
Communication);
HRESULT STDMETHODCALLTYPE CreatePins();
+ HRESULT STDMETHODCALLTYPE GetMediaSeekingFormats(PKSMULTIPLE_ITEM *FormatList);
+ HRESULT STDMETHODCALLTYPE CreateClockInstance();
+ HRESULT STDMETHODCALLTYPE PerformClockProperty(ULONG PropertyId, ULONG PropertyFlags,
PVOID OutputBuffer, ULONG OutputBufferSize);
protected:
LONG m_Ref;
IFilterGraph *m_pGraph;
@@ -188,6 +198,7 @@
PinVector m_Pins;
LPWSTR m_DevicePath;
CLSID m_DeviceInterfaceGUID;
+ HANDLE m_hClock;
};
HRESULT
@@ -196,7 +207,7 @@
IN REFIID refiid,
OUT PVOID* Output)
{
- *Output = (PVOID)0xDEADDEAD;//NULL;
+ *Output = NULL;
if (IsEqualGUID(refiid, IID_IUnknown) ||
IsEqualGUID(refiid, IID_IBaseFilter))
@@ -227,6 +238,12 @@
{
*Output = (IKsObject*)(this);
reinterpret_cast<IKsObject*>(*Output)->AddRef();
+ return NOERROR;
+ }
+ else if (IsEqualGUID(refiid, IID_IKsClock))
+ {
+ *Output = (IKsClock*)(this);
+ reinterpret_cast<IKsClock*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IReferenceClock))
@@ -335,13 +352,110 @@
//-------------------------------------------------------------------
// IKsClockPropertySet interface
//
+
+HRESULT
+STDMETHODCALLTYPE
+CKsProxy::CreateClockInstance()
+{
+ HRESULT hr;
+ HANDLE hPin = INVALID_HANDLE_VALUE;
+ ULONG Index;
+ PIN_DIRECTION PinDir;
+ IKsObject *pObject;
+ KSCLOCK_CREATE ClockCreate;
+
+ // find output pin and handle
+ for(Index = 0; Index < m_Pins.size(); Index++)
+ {
+ //get pin
+ IPin * pin = m_Pins[Index];
+ if (!pin)
+ continue;
+
+ // get direction
+ hr = pin->QueryDirection(&PinDir);
+ if (FAILED(hr))
+ continue;
+
+ // query IKsObject interface
+ hr = pin->QueryInterface(IID_IKsObject, (void**)&pObject);
+ if (FAILED(hr))
+ continue;
+
+
+ // get pin handle
+ hPin = pObject->KsGetObjectHandle();
+
+ //release IKsObject
+ pObject->Release();
+
+ if (hPin != INVALID_HANDLE_VALUE)
+ break;
+ }
+
+ if (hPin == INVALID_HANDLE_VALUE)
+ {
+ // clock can only be instantiated on a pin handle
+ return E_NOTIMPL;
+ }
+
+ if (m_hClock)
+ {
+ // release clock handle
+ CloseHandle(m_hClock);
+ }
+
+ //setup clock create request
+ ClockCreate.CreateFlags = 0;
+
+ // setup clock create request
+ hr = KsCreateClock(hPin, &ClockCreate, &m_hClock); // FIXME KsCreateClock
returns NTSTATUS
+ if (SUCCEEDED(hr))
+ {
+ // failed to create clock
+ return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
+ }
+
+ return S_OK;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CKsProxy::PerformClockProperty(
+ ULONG PropertyId,
+ ULONG PropertyFlags,
+ PVOID OutputBuffer,
+ ULONG OutputBufferSize)
+{
+ KSPROPERTY Property;
+ HRESULT hr;
+ ULONG BytesReturned;
+
+ if (!m_hClock)
+ {
+ // create clock
+ hr = CreateClockInstance();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ // setup request
+ Property.Set = KSPROPSETID_Clock;
+ Property.Id = PropertyId;
+ Property.Flags = PropertyFlags;
+
+ hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)OutputBuffer, OutputBufferSize, &BytesReturned);
+
+ return hr;
+}
+
HRESULT
STDMETHODCALLTYPE
CKsProxy::KsGetTime(
LONGLONG* Time)
{
- OutputDebugStringW(L"CKsProxy::KsGetTime NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_GET, (PVOID)Time,
sizeof(LONGLONG));
}
HRESULT
@@ -349,8 +463,8 @@
CKsProxy::KsSetTime(
LONGLONG Time)
{
- OutputDebugStringW(L"CKsProxy::KsSetTime NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsSetTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_SET,
(PVOID)&Time, sizeof(LONGLONG));
}
HRESULT
@@ -358,8 +472,8 @@
CKsProxy::KsGetPhysicalTime(
LONGLONG* Time)
{
- OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_GET,
(PVOID)Time, sizeof(LONGLONG));
}
HRESULT
@@ -368,7 +482,7 @@
LONGLONG Time)
{
OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime NotImplemented\n");
- return E_NOTIMPL;
+ return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_SET,
(PVOID)&Time, sizeof(LONGLONG));
}
HRESULT
@@ -376,8 +490,8 @@
CKsProxy::KsGetCorrelatedTime(
KSCORRELATED_TIME* CorrelatedTime)
{
- OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_GET,
(PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
}
HRESULT
@@ -385,8 +499,8 @@
CKsProxy::KsSetCorrelatedTime(
KSCORRELATED_TIME* CorrelatedTime)
{
- OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_SET,
(PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
}
HRESULT
@@ -394,8 +508,8 @@
CKsProxy::KsGetCorrelatedPhysicalTime(
KSCORRELATED_TIME* CorrelatedTime)
{
- OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime
NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,
KSPROPERTY_TYPE_GET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
}
HRESULT
@@ -403,8 +517,8 @@
CKsProxy::KsSetCorrelatedPhysicalTime(
KSCORRELATED_TIME* CorrelatedTime)
{
- OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime
NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,
KSPROPERTY_TYPE_SET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
}
HRESULT
@@ -412,8 +526,8 @@
CKsProxy::KsGetResolution(
KSRESOLUTION* Resolution)
{
- OutputDebugStringW(L"CKsProxy::KsGetResolution NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetResolution\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION, KSPROPERTY_TYPE_GET,
(PVOID)Resolution, sizeof(KSRESOLUTION));
}
HRESULT
@@ -421,8 +535,8 @@
CKsProxy::KsGetState(
KSSTATE* State)
{
- OutputDebugStringW(L"CKsProxy::KsGetState NotImplemented\n");
- return E_NOTIMPL;
+ OutputDebugStringW(L"CKsProxy::KsGetState\n");
+ return PerformClockProperty(KSPROPERTY_CLOCK_STATE, KSPROPERTY_TYPE_GET,
(PVOID)State, sizeof(KSSTATE));
}
//-------------------------------------------------------------------
@@ -433,8 +547,40 @@
CKsProxy::GetTime(
REFERENCE_TIME *pTime)
{
- OutputDebugStringW(L"CKsProxy::GetTime NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+ KSPROPERTY Property;
+ ULONG BytesReturned;
+
+ OutputDebugStringW(L"CKsProxy::GetTime\n");
+
+ if (!pTime)
+ return E_POINTER;
+
+ //
+ //FIXME locks
+ //
+
+ if (!m_hClock)
+ {
+ // create clock
+ hr = CreateClockInstance();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ // setup request
+ Property.Set = KSPROPSETID_Clock;
+ Property.Id = KSPROPERTY_CLOCK_TIME;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ // perform request
+ hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pTime, sizeof(REFERENCE_TIME), &BytesReturned);
+
+ // TODO
+ // increment value
+ //
+
+ return hr;
}
HRESULT
@@ -445,8 +591,62 @@
HEVENT hEvent,
DWORD_PTR *pdwAdviseCookie)
{
- OutputDebugStringW(L"CKsProxy::AdviseTime NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+ KSEVENT Property;
+ ULONG BytesReturned;
+ PKSEVENT_TIME_MARK Event;
+
+ OutputDebugStringW(L"CKsProxy::AdviseTime\n");
+
+ //
+ //FIXME locks
+ //
+
+ if (!pdwAdviseCookie)
+ return E_POINTER;
+
+ if (!m_hClock)
+ {
+ // create clock
+ hr = CreateClockInstance();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ // allocate event entry
+ Event = (PKSEVENT_TIME_MARK)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK));
+ if (Event)
+ {
+ // setup request
+ Property.Set = KSEVENTSETID_Clock;
+ Property.Id = KSEVENT_CLOCK_POSITION_MARK;
+ Property.Flags = KSEVENT_TYPE_ENABLE;
+
+ Event->EventData.NotificationType = KSEVENTF_EVENT_HANDLE;
+ Event->EventData.EventHandle.Event = (HANDLE)hEvent;
+ Event->EventData.Alignment.Alignment[0] = 0;
+ Event->EventData.Alignment.Alignment[1] = 0;
+ Event->MarkTime = baseTime + streamTime;
+
+ // perform request
+ hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_ENABLE_EVENT,
(PVOID)&Property, sizeof(KSEVENT), (PVOID)Event, sizeof(KSEVENT_TIME_MARK),
&BytesReturned);
+ if (SUCCEEDED(hr))
+ {
+ // store event handle
+ *pdwAdviseCookie = (DWORD_PTR)Event;
+ }
+ else
+ {
+ // failed to enable event
+ CoTaskMemFree(Event);
+ }
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+
+ return hr;
}
HRESULT
@@ -457,8 +657,63 @@
HSEMAPHORE hSemaphore,
DWORD_PTR *pdwAdviseCookie)
{
- OutputDebugStringW(L"CKsProxy::AdvisePeriodic NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+ KSEVENT Property;
+ ULONG BytesReturned;
+ PKSEVENT_TIME_INTERVAL Event;
+
+ OutputDebugStringW(L"CKsProxy::AdvisePeriodic\n");
+
+ //
+ //FIXME locks
+ //
+
+ if (!pdwAdviseCookie)
+ return E_POINTER;
+
+ if (!m_hClock)
+ {
+ // create clock
+ hr = CreateClockInstance();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ // allocate event entry
+ Event = (PKSEVENT_TIME_INTERVAL)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL));
+ if (Event)
+ {
+ // setup request
+ Property.Set = KSEVENTSETID_Clock;
+ Property.Id = KSEVENT_CLOCK_INTERVAL_MARK;
+ Property.Flags = KSEVENT_TYPE_ENABLE;
+
+ Event->EventData.NotificationType = KSEVENTF_SEMAPHORE_HANDLE;
+ Event->EventData.SemaphoreHandle.Semaphore = (HANDLE)hSemaphore;
+ Event->EventData.SemaphoreHandle.Reserved = 0;
+ Event->EventData.SemaphoreHandle.Adjustment = 1;
+ Event->TimeBase = startTime;
+ Event->Interval = periodTime;
+
+ // perform request
+ hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_ENABLE_EVENT,
(PVOID)&Property, sizeof(KSEVENT), (PVOID)Event, sizeof(KSEVENT_TIME_INTERVAL),
&BytesReturned);
+ if (SUCCEEDED(hr))
+ {
+ // store event handle
+ *pdwAdviseCookie = (DWORD_PTR)Event;
+ }
+ else
+ {
+ // failed to enable event
+ CoTaskMemFree(Event);
+ }
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+
+ return hr;
}
HRESULT
@@ -466,8 +721,28 @@
CKsProxy::Unadvise(
DWORD_PTR dwAdviseCookie)
{
- OutputDebugStringW(L"CKsProxy::Unadvise NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+ ULONG BytesReturned;
+
+ OutputDebugStringW(L"CKsProxy::Unadvise\n");
+
+ if (m_hClock)
+ {
+ //lets disable the event
+ hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_DISABLE_EVENT,
(PVOID)dwAdviseCookie, sizeof(KSEVENTDATA), 0, 0, &BytesReturned);
+ if (SUCCEEDED(hr))
+ {
+ // lets free event data
+ CoTaskMemFree((LPVOID)dwAdviseCookie);
+ }
+ }
+ else
+ {
+ // no clock available
+ hr = E_FAIL;
+ }
+
+ return hr;
}
//-------------------------------------------------------------------
@@ -478,8 +753,55 @@
CKsProxy::GetCapabilities(
DWORD *pCapabilities)
{
- OutputDebugStringW(L"CKsProxy::GetCapabilities NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr = S_OK;
+ DWORD TempCaps;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_CAPABILITIES;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetCapabilities\n");
+
+ if (!pCapabilities)
+ return E_POINTER;
+
+
+ *pCapabilities = (KS_SEEKING_CanSeekAbsolute | KS_SEEKING_CanSeekForwards |
KS_SEEKING_CanSeekBackwards | KS_SEEKING_CanGetCurrentPos |
+ KS_SEEKING_CanGetStopPos | KS_SEEKING_CanGetDuration |
KS_SEEKING_CanPlayBackwards);
+
+ KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)&pCapabilities, sizeof(KS_SEEKING_CAPABILITIES),
&BytesReturned);
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (FAILED(hr))
+ {
+ *pCapabilities = 0;
+ return hr;
+ }
+
+ TempCaps = 0;
+ // set time format
+ hr = pSeek->GetCapabilities(&TempCaps);
+ if (SUCCEEDED(hr))
+ {
+ // and with supported flags
+ *pCapabilities = (*pCapabilities & TempCaps);
+ }
+ // release IMediaSeeking interface
+ pSeek->Release();
+ }
+ return hr;
}
HRESULT
@@ -487,8 +809,75 @@
CKsProxy::CheckCapabilities(
DWORD *pCapabilities)
{
- OutputDebugStringW(L"CKsProxy::CheckCapabilities NotImplemented\n");
- return E_NOTIMPL;
+ DWORD Capabilities;
+ HRESULT hr;
+
+ OutputDebugStringW(L"CKsProxy::CheckCapabilities\n");
+
+ if (!pCapabilities)
+ return E_POINTER;
+
+ if (!*pCapabilities)
+ return E_FAIL;
+
+ hr = GetCapabilities(&Capabilities);
+ if (SUCCEEDED(hr))
+ {
+ if ((Capabilities | *pCapabilities) == Capabilities)
+ {
+ // all present
+ return S_OK;
+ }
+
+ Capabilities = (Capabilities & *pCapabilities);
+ if (Capabilities)
+ {
+ // not all present
+ *pCapabilities = Capabilities;
+ return S_FALSE;
+ }
+ // no capabilities are present
+ return E_FAIL;
+ }
+
+ return hr;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CKsProxy::GetMediaSeekingFormats(
+ PKSMULTIPLE_ITEM *FormatList)
+{
+ KSPROPERTY Property;
+ HRESULT hr;
+ ULONG BytesReturned;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_FORMATS;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ // query for format size list
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
+
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
+ {
+ // allocate format list
+ *FormatList = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned);
+ if (!*FormatList)
+ {
+ // not enough memory
+ return E_OUTOFMEMORY;
+ }
+
+ // get format list
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY,
(PVOID)&Property, sizeof(KSPROPERTY), (PVOID)*FormatList, BytesReturned,
&BytesReturned);
+ if (FAILED(hr))
+ {
+ // failed to query format list
+ CoTaskMemFree(FormatList);
+ }
+ }
+ return hr;
}
HRESULT
@@ -496,58 +885,31 @@
CKsProxy::IsFormatSupported(
const GUID *pFormat)
{
- KSPROPERTY Property;
PKSMULTIPLE_ITEM FormatList;
LPGUID pGuid;
ULONG Index;
HRESULT hr = S_FALSE;
- ULONG BytesReturned;
OutputDebugStringW(L"CKsProxy::IsFormatSupported\n");
if (!pFormat)
return E_POINTER;
- Property.Set = KSPROPSETID_MediaSeeking;
- Property.Id = KSPROPERTY_MEDIASEEKING_FORMATS;
- Property.Flags = KSPROPERTY_TYPE_GET;
-
- // query for format size list
- hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
-
- if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
- {
- // allocate format list
- FormatList = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned);
- if (!FormatList)
- {
- // not enough memory
- return E_OUTOFMEMORY;
- }
-
- // get format list
- hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY,
(PVOID)&Property, sizeof(KSPROPERTY), (PVOID)FormatList, BytesReturned,
&BytesReturned);
- if (FAILED(hr))
- {
- // failed to query format list
- CoTaskMemFree(FormatList);
- return hr;
- }
-
+ // get media formats
+ hr = GetMediaSeekingFormats(&FormatList);
+ if (SUCCEEDED(hr))
+ {
//iterate through format list
pGuid = (LPGUID)(FormatList + 1);
for(Index = 0; Index < FormatList->Count; Index++)
{
if (IsEqualGUID(*pGuid, *pFormat))
{
- OutputDebugStringW(L"CKsProxy::IsFormatSupported found
format\n");
CoTaskMemFree(FormatList);
return S_OK;
}
pGuid++;
}
-
- OutputDebugStringW(L"CKsProxy::IsFormatSupported FormatNotFound\n");
// free format list
CoTaskMemFree(FormatList);
}
@@ -589,8 +951,55 @@
CKsProxy::QueryPreferredFormat(
GUID *pFormat)
{
- OutputDebugStringW(L"CKsProxy::QueryPreferredFormat NotImplemented\n");
- return E_NOTIMPL;
+ PKSMULTIPLE_ITEM FormatList;
+ HRESULT hr;
+ ULONG Index;
+
+ OutputDebugStringW(L"CKsProxy::QueryPreferredFormat\n");
+
+ if (!pFormat)
+ return E_POINTER;
+
+ hr = GetMediaSeekingFormats(&FormatList);
+ if (SUCCEEDED(hr))
+ {
+ if (FormatList->Count)
+ {
+ CopyMemory(pFormat, (FormatList + 1), sizeof(GUID));
+ CoTaskMemFree(FormatList);
+ return S_OK;
+ }
+ CoTaskMemFree(FormatList);
+ }
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // get preferred time format
+ hr = pSeek->QueryPreferredFormat(pFormat);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE)
+ return hr;
+ }
+ }
+ hr = S_FALSE;
+ }
+
+ return hr;
}
HRESULT
@@ -598,8 +1007,45 @@
CKsProxy::GetTimeFormat(
GUID *pFormat)
{
- OutputDebugStringW(L"CKsProxy::GetTimeFormat NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetTimeFormat\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // set time format
+ hr = pSeek->GetTimeFormat(pFormat);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE)
+ break;
+ }
+ }
+ }
+ return hr;
}
HRESULT
@@ -607,8 +1053,17 @@
CKsProxy::IsUsingTimeFormat(
const GUID *pFormat)
{
- OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat NotImplemented\n");
- return E_NOTIMPL;
+ GUID Format;
+
+ OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat\n");
+
+ if (FAILED(QueryPreferredFormat(&Format)))
+ return S_FALSE;
+
+ if (IsEqualGUID(Format, *pFormat))
+ return S_OK;
+ else
+ return S_FALSE;
}
HRESULT
@@ -616,8 +1071,47 @@
CKsProxy::SetTimeFormat(
const GUID *pFormat)
{
- OutputDebugStringW(L"CKsProxy::SetTimeFormat NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
+ Property.Flags = KSPROPERTY_TYPE_SET;
+
+ OutputDebugStringW(L"CKsProxy::SetTimeFormat\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (FAILED(hr))
+ {
+ //not supported
+ break;
+ }
+ // set time format
+ hr = pSeek->SetTimeFormat(pFormat);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (FAILED(hr))
+ break;
+ }
+ }
+ return hr;
}
HRESULT
@@ -625,8 +1119,45 @@
CKsProxy::GetDuration(
LONGLONG *pDuration)
{
- OutputDebugStringW(L"CKsProxy::GetDuration NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_DURATION;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetDuration\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pDuration, sizeof(LONGLONG), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // get duration
+ hr = pSeek->GetStopPosition(pDuration);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ }
+ return hr;
}
HRESULT
@@ -634,8 +1165,45 @@
CKsProxy::GetStopPosition(
LONGLONG *pStop)
{
- OutputDebugStringW(L"CKsProxy::GetStopPosition NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_STOPPOSITION;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetStopPosition\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pStop, sizeof(LONGLONG), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // get stop position
+ hr = pSeek->GetStopPosition(pStop);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ }
+ return hr;
}
HRESULT
@@ -643,8 +1211,45 @@
CKsProxy::GetCurrentPosition(
LONGLONG *pCurrent)
{
- OutputDebugStringW(L"CKsProxy::GetCurrentPosition NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_POSITION;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetCurrentPosition\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pCurrent, sizeof(LONGLONG), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // get current position
+ hr = pSeek->GetCurrentPosition(pCurrent);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ }
+ return hr;
}
HRESULT
@@ -655,8 +1260,74 @@
LONGLONG Source,
const GUID *pSourceFormat)
{
- OutputDebugStringW(L"CKsProxy::ConvertTimeFormat NotImplemented\n");
- return E_NOTIMPL;
+ KSP_TIMEFORMAT Property;
+ ULONG BytesReturned, Index;
+ GUID SourceFormat, TargetFormat;
+ HRESULT hr;
+
+ Property.Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Property.Id = KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT;
+ Property.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::ConvertTimeFormat\n");
+
+ if (!pTargetFormat)
+ {
+ // get current format
+ hr = GetTimeFormat(&TargetFormat);
+ if (FAILED(hr))
+ return hr;
+
+ pTargetFormat = &TargetFormat;
+ }
+
+ if (!pSourceFormat)
+ {
+ // get current format
+ hr = GetTimeFormat(&SourceFormat);
+ if (FAILED(hr))
+ return hr;
+
+ pSourceFormat = &SourceFormat;
+ }
+
+ Property.SourceFormat = *pSourceFormat;
+ Property.TargetFormat = *pTargetFormat;
+ Property.Time = Source;
+
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSP_TIMEFORMAT), (PVOID)pTarget, sizeof(LONGLONG), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ //default error
+ hr = E_NOTIMPL;
+
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // convert time format
+ hr = pSeek->ConvertTimeFormat(pTarget, pTargetFormat, Source,
pSourceFormat);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ }
+
+ return hr;
}
HRESULT
@@ -667,8 +1338,71 @@
LONGLONG *pStop,
DWORD dwStopFlags)
{
- OutputDebugStringW(L"CKsProxy::SetPositions NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ KSPROPERTY_POSITIONS Positions;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_POSITIONS;
+ Property.Flags = KSPROPERTY_TYPE_SET;
+
+ Positions.Current = *pCurrent;
+ Positions.CurrentFlags = (KS_SEEKING_FLAGS)dwCurrentFlags;
+ Positions.Stop = *pStop;
+ Positions.StopFlags = (KS_SEEKING_FLAGS)dwStopFlags;
+
+ OutputDebugStringW(L"CKsProxy::SetPositions\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)&Positions, sizeof(KSPROPERTY_POSITIONS),
&BytesReturned);
+ if (SUCCEEDED(hr))
+ {
+ if (dwCurrentFlags & AM_SEEKING_ReturnTime)
+ {
+ // retrieve current position
+ hr = GetCurrentPosition(pCurrent);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ if (dwStopFlags & AM_SEEKING_ReturnTime)
+ {
+ // retrieve current position
+ hr = GetStopPosition(pStop);
+ }
+ }
+ return hr;
+ }
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ hr = E_NOTIMPL;
+
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // set positions
+ hr = pSeek->SetPositions(pCurrent, dwCurrentFlags, pStop,
dwStopFlags);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (FAILED(hr))
+ break;
+ }
+ }
+ }
+
+ return hr;
}
HRESULT
@@ -677,8 +1411,15 @@
LONGLONG *pCurrent,
LONGLONG *pStop)
{
- OutputDebugStringW(L"CKsProxy::GetPositions NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+
+ OutputDebugStringW(L"CKsProxy::GetPositions\n");
+
+ hr = GetCurrentPosition(pCurrent);
+ if (SUCCEEDED(hr))
+ hr = GetStopPosition(pStop);
+
+ return hr;
}
HRESULT
@@ -687,8 +1428,52 @@
LONGLONG *pEarliest,
LONGLONG *pLatest)
{
- OutputDebugStringW(L"CKsProxy::GetAvailable NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ KSPROPERTY_MEDIAAVAILABLE Media;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_AVAILABLE;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetAvailable\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)&Media, sizeof(KSPROPERTY_MEDIAAVAILABLE),
&BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ hr = E_NOTIMPL;
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // delegate call
+ hr = pSeek->GetAvailable(pEarliest, pLatest);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ }
+ else if (SUCCEEDED(hr))
+ {
+ *pEarliest = Media.Earliest;
+ *pLatest = Media.Latest;
+ }
+
+ return hr;
}
HRESULT
@@ -696,7 +1481,6 @@
CKsProxy::SetRate(
double dRate)
{
- OutputDebugStringW(L"CKsProxy::SetRate NotImplemented\n");
return E_NOTIMPL;
}
@@ -705,7 +1489,6 @@
CKsProxy::GetRate(
double *pdRate)
{
- OutputDebugStringW(L"CKsProxy::GetRate NotImplemented\n");
return E_NOTIMPL;
}
@@ -714,8 +1497,45 @@
CKsProxy::GetPreroll(
LONGLONG *pllPreroll)
{
- OutputDebugStringW(L"CKsProxy::GetPreroll NotImplemented\n");
- return E_NOTIMPL;
+ KSPROPERTY Property;
+ ULONG BytesReturned, Index;
+ HRESULT hr;
+
+ Property.Set = KSPROPSETID_MediaSeeking;
+ Property.Id = KSPROPERTY_MEDIASEEKING_PREROLL;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ OutputDebugStringW(L"CKsProxy::GetPreroll\n");
+
+ hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)pllPreroll, sizeof(LONGLONG), &BytesReturned);
+ if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr ==
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
+ {
+ // check if all plugins support it
+ for(Index = 0; Index < m_Plugins.size(); Index++)
+ {
+ // get plugin
+ IUnknown * Plugin = m_Plugins[Index];
+
+ if (!Plugin)
+ continue;
+
+ // query for IMediaSeeking interface
+ IMediaSeeking *pSeek = NULL;
+ hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
+ if (SUCCEEDED(hr))
+ {
+ // get preroll
+ hr = pSeek->GetPreroll(pllPreroll);
+ // release IMediaSeeking interface
+ pSeek->Release();
+
+ if (hr != S_FALSE) // plugin implements it
+ break;
+ }
+ }
+ hr = E_NOTIMPL;
+ }
+ return hr;
}
//-------------------------------------------------------------------
@@ -922,8 +1742,23 @@
REFGUID InterfaceId,
LPVOID* Interface)
{
- OutputDebugStringW(L"CKsProxy::CreateNodeInstance NotImplemented\n");
- return E_NOTIMPL;
+ HRESULT hr;
+
+ OutputDebugStringW(L"CKsProxy::CreateNodeInstance\n");
+
+ *Interface = NULL;
+
+ if (IsEqualIID(IID_IUnknown, InterfaceId) || !UnkOuter)
+ {
+ hr = CKsNode_Constructor(UnkOuter, m_hDevice, NodeId, DesiredAccess, InterfaceId,
Interface);
+ }
+ else
+ {
+ // interface not supported
+ hr = E_NOINTERFACE;
+ }
+
+ return hr;
}
//-------------------------------------------------------------------
@@ -1119,7 +1954,16 @@
return NOERROR;
}
-
+//-------------------------------------------------------------------
+// IKsClock interface
+//
+
+HANDLE
+STDMETHODCALLTYPE
+CKsProxy::KsGetClockHandle()
+{
+ return m_hClock;
+}
//-------------------------------------------------------------------
@@ -1647,6 +2491,90 @@
CKsProxy::SetSyncSource(
IReferenceClock *pClock)
{
+ HRESULT hr;
+ IKsClock *pKsClock;
+ HANDLE hClock, hPin;
+ ULONG Index;
+ IPin * pin;
+ IKsObject * pObject;
+ KSPROPERTY Property;
+ ULONG BytesReturned;
+ PIN_DIRECTION PinDir;
+
+// Plug In Distributor: IKsClock
+
+
+ // 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
+ pKsClock->Release();
+ return E_FAIL;
+ }
+
+ // distribute clock to all pins
+ for(Index = 0; Index < m_Pins.size(); Index++)
+ {
+ // get current pin
+ pin = m_Pins[Index];
+ if (!pin)
+ continue;
+
+ // get IKsObject interface
+ hr = pin->QueryInterface(IID_IKsObject, (void **)&pObject);
+ if (SUCCEEDED(hr))
+ {
+ // get pin handle
+ hPin = pObject->KsGetObjectHandle();
+ if (hPin != INVALID_HANDLE_VALUE && hPin)
+ {
+ // set clock
+ Property.Set = KSPROPSETID_Stream;
+ Property.Id = KSPROPERTY_STREAM_MASTERCLOCK;
+ Property.Flags = KSPROPERTY_TYPE_SET;
+
+ // set master clock
+ hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY,
(PVOID)&Property, sizeof(KSPROPERTY), (PVOID)hClock, sizeof(HANDLE),
&BytesReturned);
+
+ if (FAILED(hr))
+ {
+ if (hr != MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,
ERROR_SET_NOT_FOUND) &&
+ hr != MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,
ERROR_NOT_FOUND))
+ {
+ // failed to set master clock
+ pKsClock->Release();
+ pObject->Release();
+ return hr;
+ }
+ }
+ }
+ // release IKsObject
+ pObject->Release();
+ }
+
+ // now get the direction
+ hr = pin->QueryDirection(&PinDir);
+ if (SUCCEEDED(hr))
+ {
+ if (PinDir == PINDIR_OUTPUT)
+ {
+ // notify pin via
+ //CBaseStreamControl::SetSyncSource(pClock)
+ }
+ }
+ }
+
if (pClock)
{
pClock->AddRef();
@@ -1727,6 +2655,9 @@
pInfo->achName[0] = L'\0';
pInfo->pGraph = m_pGraph;
+
+ if (m_pGraph)
+ m_pGraph->AddRef();
return S_OK;
}
Modified: trunk/reactos/include/psdk/ks.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/ks.h?rev=4617…
==============================================================================
--- trunk/reactos/include/psdk/ks.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/ks.h [iso-8859-1] Sat Mar 13 18:36:30 2010
@@ -724,8 +724,10 @@
Properties/Methods/Events
*/
-#define KSPROPSETID_Stream \
+#define STATIC_KSPROPSETID_Stream\
0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
+DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream);
+#define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream)
typedef enum
{
@@ -2091,7 +2093,7 @@
typedef struct _KSEVENT_ENTRY KSEVENT_ENTRY, *PKSEVENT_ENTRY;
#if defined(_NTDDK_)
-
+
typedef NTSTATUS (NTAPI *PFNKSADDEVENT)(
IN PIRP Irp,
IN PKSEVENTDATA EventData,