ReactOS  0.4.14-dev-55-g2da92ac
clockforward.cpp
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4  * FILE: dll/directx/ksproxy/clockforward.cpp
5  * PURPOSE: IKsClockForwarder interface
6  *
7  * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 #include "precomp.h"
10 
11 const GUID IID_IKsClockForwarder = {0x877e4352, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
12 
14 
15 class CKsClockForwarder : public IDistributorNotify,
16  public IKsObject
17 {
18 public:
20 
22  {
24  return m_Ref;
25  }
27  {
29 
30  if (!m_Ref)
31  {
32  delete this;
33  return 0;
34  }
35  return m_Ref;
36  }
37 
38  // IDistributorNotify interface
44 
45  // IKsObject interface
47 
49  virtual ~CKsClockForwarder(){};
51 protected:
62 
64 };
65 
67  HANDLE handle) : m_Ref(0),
68  m_Handle(handle),
69  m_Clock(0),
70  m_hEvent(NULL),
71  m_hThread(NULL),
72  m_ThreadStarted(FALSE),
73  m_PendingStop(FALSE),
74  m_ForceStart(FALSE),
75  m_State(KSSTATE_STOP),
76  m_Time(0)
77 {
78 }
79 
80 HRESULT
83  IN REFIID refiid,
84  OUT PVOID* Output)
85 {
86  if (IsEqualGUID(refiid, IID_IUnknown))
87  {
88  *Output = PVOID(this);
89  reinterpret_cast<IUnknown*>(*Output)->AddRef();
90  return NOERROR;
91  }
92  if (IsEqualGUID(refiid, IID_IKsObject) ||
94  {
95  *Output = (IKsObject*)(this);
96  reinterpret_cast<IKsObject*>(*Output)->AddRef();
97  return NOERROR;
98  }
99 
100  if (IsEqualGUID(refiid, IID_IDistributorNotify))
101  {
102  *Output = (IDistributorNotify*)(this);
103  reinterpret_cast<IDistributorNotify*>(*Output)->AddRef();
104  return NOERROR;
105  }
106 
107  return E_NOINTERFACE;
108 }
109 
110 //-------------------------------------------------------------------
111 // IDistributorNotify interface
112 //
113 
114 
115 HRESULT
118 {
119 #ifdef KSPROXY_TRACE
120  WCHAR Buffer[200];
121  swprintf(Buffer, L"CKsClockForwarder::Stop m_ThreadStarted %u m_PendingStop %u m_hThread %p m_hEvent %p m_Handle %p\n", m_ThreadStarted, m_PendingStop, m_hThread, m_hEvent, m_Handle);
123 #endif
124 
125  m_Time = 0;
126  if (m_ThreadStarted)
127  {
128  // signal pending stop
129  m_PendingStop = true;
130 
131  assert(m_hThread);
132  assert(m_hEvent);
133 
134  // set stop event
136 
137  // wait untill the thread has finished
139 
140  // close thread handle
142 
143  // zero handle
144  m_hThread = NULL;
145  }
146 
147  if (m_hEvent)
148  {
149  // close stop event
151  m_hEvent = NULL;
152  }
153 
154  m_PendingStop = false;
155 
157  return NOERROR;
158 }
159 
160 HRESULT
163 {
164 #ifdef KSPROXY_TRACE
165  OutputDebugString("CKsClockForwarder::Pause\n");
166 #endif
167 
168  if (!m_hEvent)
169  {
171  if (!m_hEvent)
173  }
174 
175  if (m_State <= KSSTATE_PAUSE)
176  {
177  if (m_State == KSSTATE_STOP)
179 
180  if (m_State == KSSTATE_ACQUIRE)
182  }
183  else
184  {
185  if (!m_ForceStart)
186  {
188  }
189  }
190 
191  if (!m_hThread)
192  {
194  if (!m_hThread)
196  }
197 
198  return NOERROR;
199 }
200 
201 HRESULT
204  REFERENCE_TIME tStart)
205 {
206 #ifdef KSPROXY_TRACE
207  OutputDebugString("CKsClockForwarder::Run\n");
208 #endif
209 
210  m_Time = tStart;
211 
212  if (!m_hEvent || !m_hThread)
213  {
214  m_ForceStart = TRUE;
215  HRESULT hr = Pause();
217 
218  if (FAILED(hr))
219  return hr;
220  }
221 
222  assert(m_hThread);
223 
226 
227  return NOERROR;
228 }
229 
230 HRESULT
233  IReferenceClock *pClock)
234 {
235 #ifdef KSPROXY_TRACE
236  OutputDebugString("CKsClockForwarder::SetSyncSource\n");
237 #endif
238 
239  if (pClock)
240  pClock->AddRef();
241 
242  if (m_Clock)
243  m_Clock->Release();
244 
245 
246  m_Clock = pClock;
247  return NOERROR;
248 }
249 
250 HRESULT
253 {
254 #ifdef KSPROXY_TRACE
255  OutputDebugString("CKsClockForwarder::NotifyGraphChange\n");
256 #endif
257 
258  return NOERROR;
259 }
260 
261 //-------------------------------------------------------------------
262 // IKsObject interface
263 //
264 
265 HANDLE
268 {
269  return m_Handle;
270 }
271 
272 //-------------------------------------------------------------------
273 HRESULT
276 {
279 
283 
285  if (SUCCEEDED(hr))
286  m_State = State;
287 
288 #ifdef KSPROXY_TRACE
289  WCHAR Buffer[100];
290  swprintf(Buffer, L"CKsClockForwarder::SetClockState m_State %u State %u hr %lx\n", m_State, State, hr);
292 #endif
293 
294  return hr;
295 }
296 
297 DWORD
298 WINAPI
300 {
303 
305 
306  Fwd->m_ThreadStarted = TRUE;
307 
308  do
309  {
310  if (Fwd->m_PendingStop)
311  break;
312 
313  if (Fwd->m_State != KSSTATE_RUN)
315 
320 
321  Fwd->m_Clock->GetTime(&Time);
322  Time -= Fwd->m_Time;
323 
325  }
326  while(TRUE);
327 
328  Fwd->m_ThreadStarted = FALSE;
329  return NOERROR;
330 }
331 
332 HRESULT
333 WINAPI
335  IUnknown * pUnkOuter,
336  REFIID riid,
337  LPVOID * ppv)
338 {
339  HRESULT hr;
340  HANDLE handle;
341 
342 #ifdef KSPROXY_TRACE
343  OutputDebugStringW(L"CKsClockForwarder_Constructor\n");
344 #endif
345 
346  // open default clock
348 
349  if (hr != NOERROR)
350  {
351 #ifdef KSPROXY_TRACE
352  OutputDebugString("CKsClockForwarder_Constructor failed to open device\n");
353 #endif
354  return hr;
355  }
356 
358 
359  if (!clock)
360  {
361  // free clock handle
363  return E_OUTOFMEMORY;
364  }
365 
366  if (FAILED(clock->QueryInterface(riid, ppv)))
367  {
368  /* not supported */
369  delete clock;
370  return E_NOINTERFACE;
371  }
372 
373  return NOERROR;
374 }
HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart)
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
#define IN
Definition: typedefs.h:38
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT hr
Definition: shlfolder.c:183
_In_ BOOLEAN Release
Definition: classpnp.h:929
#define NOERROR
Definition: winerror.h:2354
const GUID IID_IKsObject
REFIID riid
Definition: precomp.h:44
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
KSDDKAPI HRESULT WINAPI KsSynchronousDeviceControl(HANDLE Handle, ULONG IoControl, PVOID InBuffer, ULONG InLength, PVOID OutBuffer, ULONG OutLength, PULONG BytesReturned)
Definition: ksproxy.cpp:34
REFERENCE_TIME m_Time
#define OutputDebugString
Definition: winbase.h:3707
HRESULT STDMETHODCALLTYPE NotifyGraphChange()
friend DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
void WINAPI SHIM_OBJ_NAME() OutputDebugStringW(LPCWSTR lpOutputString)
Definition: ignoredbgout.c:23
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define GENERIC_WRITE
Definition: nt_native.h:90
const GUID KSPROPSETID_Clock
Definition: pin.c:115
#define STDMETHODIMP
Definition: basetyps.h:43
ULONG Release()
HRESULT STDMETHODCALLTYPE SetClockState(KSSTATE State)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
HRESULT STDMETHODCALLTYPE Stop()
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:8
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
CKsClockForwarder(HANDLE handle)
#define SEVERITY_ERROR
Definition: winerror.h:65
ULONG AddRef()
static const WCHAR L[]
Definition: oid.c:1250
const GUID IID_IKsClockForwarder
#define InterlockedDecrement
Definition: armddk.h:52
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: arc.h:85
STDMETHODIMP_(ULONG) Release()
LPVOID lpParameter
Definition: kernel32.h:241
#define GENERIC_READ
Definition: compat.h:124
HANDLE STDMETHODCALLTYPE KsGetObjectHandle()
_In_ DWORD Property
Definition: setupapi.h:1545
#define FACILITY_WIN32
Definition: winerror.h:27
HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock)
enum State_ State
Definition: pofuncs.h:54
#define InterlockedIncrement
Definition: armddk.h:53
KSSTATE
Definition: ks.h:1214
virtual ~CKsClockForwarder()
_In_ FILTER_INFORMATION_CLASS _In_ ULONG _Out_ PULONG BytesReturned
Definition: fltkernel.h:1716
STDMETHODIMP_(ULONG) AddRef()
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
_Check_return_ _CRTIMP clock_t __cdecl clock(void)
Definition: clock.c:23
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
const GUID IID_IDistributorNotify
#define KSCATEGORY_CLOCK
Definition: ks.h:215
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
HRESULT STDMETHODCALLTYPE Pause()
#define INFINITE
Definition: serial.h:102
IReferenceClock * m_Clock
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
HRESULT GetTime([out] REFERENCE_TIME *pTime)
HRESULT WINAPI CKsClockForwarder_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv)
static PLARGE_INTEGER Time
Definition: time.c:105
#define SUCCEEDED(hr)
Definition: intsafe.h:57
KSDDKAPI HRESULT WINAPI KsOpenDefaultDevice(REFGUID Category, ACCESS_MASK Access, PHANDLE DeviceHandle)
Definition: ksproxy.cpp:101