ntdll: Connect syscall frames across user callbacks on x86-64.
[wine.git] / dlls / mf / quality.c
bloba611d6fdaede3aaca7e08ace542d4d1b3bc36c0e
1 /*
2 * Copyright 2022 Nikolay Sivov for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "mf_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
30 enum quality_manager_state
32 QUALITY_MANAGER_READY = 0,
33 QUALITY_MANAGER_SHUT_DOWN,
36 struct quality_manager
38 IMFQualityManager IMFQualityManager_iface;
39 IMFClockStateSink IMFClockStateSink_iface;
40 LONG refcount;
42 IMFTopology *topology;
43 IMFPresentationClock *clock;
44 unsigned int state;
45 CRITICAL_SECTION cs;
48 static struct quality_manager *impl_from_IMFQualityManager(IMFQualityManager *iface)
50 return CONTAINING_RECORD(iface, struct quality_manager, IMFQualityManager_iface);
53 static struct quality_manager *impl_from_IMFClockStateSink(IMFClockStateSink *iface)
55 return CONTAINING_RECORD(iface, struct quality_manager, IMFClockStateSink_iface);
58 static HRESULT WINAPI standard_quality_manager_QueryInterface(IMFQualityManager *iface, REFIID riid, void **out)
60 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
62 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
64 if (IsEqualIID(riid, &IID_IMFQualityManager) ||
65 IsEqualIID(riid, &IID_IUnknown))
67 *out = iface;
69 else if (IsEqualIID(riid, &IID_IMFClockStateSink))
71 *out = &manager->IMFClockStateSink_iface;
73 else
75 WARN("Unsupported %s.\n", debugstr_guid(riid));
76 *out = NULL;
77 return E_NOINTERFACE;
80 IUnknown_AddRef((IUnknown *)*out);
81 return S_OK;
84 static ULONG WINAPI standard_quality_manager_AddRef(IMFQualityManager *iface)
86 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
87 ULONG refcount = InterlockedIncrement(&manager->refcount);
89 TRACE("%p, refcount %lu.\n", iface, refcount);
91 return refcount;
94 static ULONG WINAPI standard_quality_manager_Release(IMFQualityManager *iface)
96 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
97 ULONG refcount = InterlockedDecrement(&manager->refcount);
99 TRACE("%p, refcount %lu.\n", iface, refcount);
101 if (!refcount)
103 if (manager->clock)
104 IMFPresentationClock_Release(manager->clock);
105 if (manager->topology)
106 IMFTopology_Release(manager->topology);
107 DeleteCriticalSection(&manager->cs);
108 free(manager);
111 return refcount;
114 static void standard_quality_manager_set_topology(struct quality_manager *manager, IMFTopology *topology)
116 if (manager->topology)
117 IMFTopology_Release(manager->topology);
118 manager->topology = topology;
119 if (manager->topology)
120 IMFTopology_AddRef(manager->topology);
123 static HRESULT WINAPI standard_quality_manager_NotifyTopology(IMFQualityManager *iface, IMFTopology *topology)
125 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
126 HRESULT hr = S_OK;
128 TRACE("%p, %p.\n", iface, topology);
130 EnterCriticalSection(&manager->cs);
131 if (manager->state == QUALITY_MANAGER_SHUT_DOWN)
132 hr = MF_E_SHUTDOWN;
133 else
135 standard_quality_manager_set_topology(manager, topology);
137 LeaveCriticalSection(&manager->cs);
139 return hr;
142 static void standard_quality_manager_release_clock(struct quality_manager *manager)
144 if (manager->clock)
146 IMFPresentationClock_RemoveClockStateSink(manager->clock, &manager->IMFClockStateSink_iface);
147 IMFPresentationClock_Release(manager->clock);
149 manager->clock = NULL;
152 static HRESULT WINAPI standard_quality_manager_NotifyPresentationClock(IMFQualityManager *iface,
153 IMFPresentationClock *clock)
155 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
156 HRESULT hr = S_OK;
158 TRACE("%p, %p.\n", iface, clock);
160 EnterCriticalSection(&manager->cs);
161 if (manager->state == QUALITY_MANAGER_SHUT_DOWN)
162 hr = MF_E_SHUTDOWN;
163 else if (!clock)
164 hr = E_POINTER;
165 else
167 standard_quality_manager_release_clock(manager);
168 manager->clock = clock;
169 IMFPresentationClock_AddRef(manager->clock);
170 if (FAILED(IMFPresentationClock_AddClockStateSink(manager->clock, &manager->IMFClockStateSink_iface)))
171 WARN("Failed to set state sink.\n");
173 LeaveCriticalSection(&manager->cs);
175 return hr;
178 static HRESULT WINAPI standard_quality_manager_NotifyProcessInput(IMFQualityManager *iface, IMFTopologyNode *node,
179 LONG input_index, IMFSample *sample)
181 TRACE("%p, %p, %ld, %p stub.\n", iface, node, input_index, sample);
183 return E_NOTIMPL;
186 static HRESULT WINAPI standard_quality_manager_NotifyProcessOutput(IMFQualityManager *iface, IMFTopologyNode *node,
187 LONG output_index, IMFSample *sample)
189 TRACE("%p, %p, %ld, %p stub.\n", iface, node, output_index, sample);
191 return E_NOTIMPL;
194 static HRESULT WINAPI standard_quality_manager_NotifyQualityEvent(IMFQualityManager *iface, IUnknown *object,
195 IMFMediaEvent *event)
197 FIXME("%p, %p, %p stub.\n", iface, object, event);
199 return E_NOTIMPL;
202 static HRESULT WINAPI standard_quality_manager_Shutdown(IMFQualityManager *iface)
204 struct quality_manager *manager = impl_from_IMFQualityManager(iface);
206 TRACE("%p.\n", iface);
208 EnterCriticalSection(&manager->cs);
209 if (manager->state != QUALITY_MANAGER_SHUT_DOWN)
211 standard_quality_manager_release_clock(manager);
212 standard_quality_manager_set_topology(manager, NULL);
213 manager->state = QUALITY_MANAGER_SHUT_DOWN;
215 LeaveCriticalSection(&manager->cs);
217 return S_OK;
220 static const IMFQualityManagerVtbl standard_quality_manager_vtbl =
222 standard_quality_manager_QueryInterface,
223 standard_quality_manager_AddRef,
224 standard_quality_manager_Release,
225 standard_quality_manager_NotifyTopology,
226 standard_quality_manager_NotifyPresentationClock,
227 standard_quality_manager_NotifyProcessInput,
228 standard_quality_manager_NotifyProcessOutput,
229 standard_quality_manager_NotifyQualityEvent,
230 standard_quality_manager_Shutdown,
233 static HRESULT WINAPI standard_quality_manager_sink_QueryInterface(IMFClockStateSink *iface,
234 REFIID riid, void **obj)
236 struct quality_manager *manager = impl_from_IMFClockStateSink(iface);
237 return IMFQualityManager_QueryInterface(&manager->IMFQualityManager_iface, riid, obj);
240 static ULONG WINAPI standard_quality_manager_sink_AddRef(IMFClockStateSink *iface)
242 struct quality_manager *manager = impl_from_IMFClockStateSink(iface);
243 return IMFQualityManager_AddRef(&manager->IMFQualityManager_iface);
246 static ULONG WINAPI standard_quality_manager_sink_Release(IMFClockStateSink *iface)
248 struct quality_manager *manager = impl_from_IMFClockStateSink(iface);
249 return IMFQualityManager_Release(&manager->IMFQualityManager_iface);
252 static HRESULT WINAPI standard_quality_manager_sink_OnClockStart(IMFClockStateSink *iface,
253 MFTIME systime, LONGLONG offset)
255 return S_OK;
258 static HRESULT WINAPI standard_quality_manager_sink_OnClockStop(IMFClockStateSink *iface,
259 MFTIME systime)
261 return S_OK;
264 static HRESULT WINAPI standard_quality_manager_sink_OnClockPause(IMFClockStateSink *iface,
265 MFTIME systime)
267 return S_OK;
270 static HRESULT WINAPI standard_quality_manager_sink_OnClockRestart(IMFClockStateSink *iface,
271 MFTIME systime)
273 return S_OK;
276 static HRESULT WINAPI standard_quality_manager_sink_OnClockSetRate(IMFClockStateSink *iface,
277 MFTIME systime, float rate)
279 return S_OK;
282 static const IMFClockStateSinkVtbl standard_quality_manager_sink_vtbl =
284 standard_quality_manager_sink_QueryInterface,
285 standard_quality_manager_sink_AddRef,
286 standard_quality_manager_sink_Release,
287 standard_quality_manager_sink_OnClockStart,
288 standard_quality_manager_sink_OnClockStop,
289 standard_quality_manager_sink_OnClockPause,
290 standard_quality_manager_sink_OnClockRestart,
291 standard_quality_manager_sink_OnClockSetRate,
294 HRESULT WINAPI MFCreateStandardQualityManager(IMFQualityManager **manager)
296 struct quality_manager *object;
298 TRACE("%p.\n", manager);
300 if (!(object = calloc(1, sizeof(*object))))
301 return E_OUTOFMEMORY;
303 object->IMFQualityManager_iface.lpVtbl = &standard_quality_manager_vtbl;
304 object->IMFClockStateSink_iface.lpVtbl = &standard_quality_manager_sink_vtbl;
305 object->refcount = 1;
306 InitializeCriticalSection(&object->cs);
308 *manager = &object->IMFQualityManager_iface;
310 return S_OK;