1 /* DirectShow Sample Grabber object (QEDIT.DLL)
3 * Copyright 2009 Paul Chitescu
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "qedit_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(qedit);
35 static WCHAR const vendor_name[] = { 'W', 'i', 'n', 'e', 0 };
37 /* Sample Grabber filter implementation */
38 typedef struct _SG_Impl {
39 const IBaseFilterVtbl* IBaseFilter_Vtbl;
40 const ISampleGrabberVtbl* ISampleGrabber_Vtbl;
41 /* TODO: IMediaPosition, IMediaSeeking, IQualityControl */
45 IMemAllocator *allocator;
46 IReferenceClock *refClock;
49 /* Get the SampleGrabber implementation This pointer from various interface pointers */
50 static inline SG_Impl *impl_from_IBaseFilter(IBaseFilter *iface)
52 return (SG_Impl *)((char*)iface - FIELD_OFFSET(SG_Impl, IBaseFilter_Vtbl));
55 static inline SG_Impl *impl_from_ISampleGrabber(ISampleGrabber *iface)
57 return (SG_Impl *)((char*)iface - FIELD_OFFSET(SG_Impl, ISampleGrabber_Vtbl));
61 /* Cleanup at end of life */
62 static void SampleGrabber_cleanup(SG_Impl *This)
64 TRACE("(%p)\n", This);
65 if (This->info.pGraph)
66 WARN("(%p) still joined to filter graph %p\n", This, This->info.pGraph);
68 IMemAllocator_Release(This->allocator);
70 IReferenceClock_Release(This->refClock);
73 /* Common helper AddRef called from all interfaces */
74 static ULONG SampleGrabber_addref(SG_Impl *This)
76 ULONG refCount = InterlockedIncrement(&This->refCount);
77 TRACE("(%p) new ref = %u\n", This, refCount);
81 /* Common helper Release called from all interfaces */
82 static ULONG SampleGrabber_release(SG_Impl *This)
84 ULONG refCount = InterlockedDecrement(&This->refCount);
85 TRACE("(%p) new ref = %u\n", This, refCount);
88 SampleGrabber_cleanup(This);
95 /* Common helper QueryInterface called from all interfaces */
96 static HRESULT SampleGrabber_query(SG_Impl *This, REFIID riid, void **ppvObject)
98 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
100 if (IsEqualIID(riid, &IID_IUnknown) ||
101 IsEqualIID(riid, &IID_IPersist) ||
102 IsEqualIID(riid, &IID_IMediaFilter) ||
103 IsEqualIID(riid, &IID_IBaseFilter)) {
104 SampleGrabber_addref(This);
105 *ppvObject = &(This->IBaseFilter_Vtbl);
108 else if (IsEqualIID(riid, &IID_ISampleGrabber)) {
109 SampleGrabber_addref(This);
110 *ppvObject = &(This->ISampleGrabber_Vtbl);
113 else if (IsEqualIID(riid, &IID_IMemInputPin))
114 FIXME("IMemInputPin not implemented\n");
115 else if (IsEqualIID(riid, &IID_IMediaPosition))
116 FIXME("IMediaPosition not implemented\n");
117 else if (IsEqualIID(riid, &IID_IMediaSeeking))
118 FIXME("IMediaSeeking not implemented\n");
119 else if (IsEqualIID(riid, &IID_IQualityControl))
120 FIXME("IQualityControl not implemented\n");
122 WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject);
123 return E_NOINTERFACE;
127 /* SampleGrabber implementation of IBaseFilter interface */
130 static HRESULT WINAPI
131 SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppvObject)
133 return SampleGrabber_query(impl_from_IBaseFilter(iface), riid, ppvObject);
138 SampleGrabber_IBaseFilter_AddRef(IBaseFilter *iface)
140 return SampleGrabber_addref(impl_from_IBaseFilter(iface));
145 SampleGrabber_IBaseFilter_Release(IBaseFilter *iface)
147 return SampleGrabber_release(impl_from_IBaseFilter(iface));
151 static HRESULT WINAPI
152 SampleGrabber_IBaseFilter_GetClassID(IBaseFilter *iface, CLSID *pClassID)
154 TRACE("(%p)\n", pClassID);
157 *pClassID = CLSID_SampleGrabber;
162 static HRESULT WINAPI
163 SampleGrabber_IBaseFilter_Stop(IBaseFilter *iface)
165 SG_Impl *This = impl_from_IBaseFilter(iface);
166 TRACE("(%p)\n", This);
167 This->state = State_Stopped;
172 static HRESULT WINAPI
173 SampleGrabber_IBaseFilter_Pause(IBaseFilter *iface)
175 SG_Impl *This = impl_from_IBaseFilter(iface);
176 TRACE("(%p)\n", This);
177 This->state = State_Paused;
182 static HRESULT WINAPI
183 SampleGrabber_IBaseFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
185 SG_Impl *This = impl_from_IBaseFilter(iface);
186 TRACE("(%p)\n", This);
187 This->state = State_Running;
192 static HRESULT WINAPI
193 SampleGrabber_IBaseFilter_GetState(IBaseFilter *iface, DWORD msTout, FILTER_STATE *state)
195 SG_Impl *This = impl_from_IBaseFilter(iface);
196 TRACE("(%p)->(%u, %p)\n", This, msTout, state);
199 *state = This->state;
204 static HRESULT WINAPI
205 SampleGrabber_IBaseFilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
207 SG_Impl *This = impl_from_IBaseFilter(iface);
208 TRACE("(%p)->(%p)\n", This, clock);
209 if (clock != This->refClock)
212 IReferenceClock_AddRef(clock);
214 IReferenceClock_Release(This->refClock);
215 This->refClock = clock;
221 static HRESULT WINAPI
222 SampleGrabber_IBaseFilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **clock)
224 SG_Impl *This = impl_from_IBaseFilter(iface);
225 TRACE("(%p)->(%p)\n", This, clock);
229 IReferenceClock_AddRef(This->refClock);
230 *clock = This->refClock;
235 static HRESULT WINAPI
236 SampleGrabber_IBaseFilter_EnumPins(IBaseFilter *iface, IEnumPins **pins)
238 SG_Impl *This = impl_from_IBaseFilter(iface);
239 FIXME("(%p)->(%p): stub\n", This, pins);
242 return E_OUTOFMEMORY;
246 static HRESULT WINAPI
247 SampleGrabber_IBaseFilter_FindPin(IBaseFilter *iface, LPCWSTR id, IPin **pin)
249 SG_Impl *This = impl_from_IBaseFilter(iface);
250 FIXME("(%p)->(%s, %p): stub\n", This, debugstr_w(id), pin);
254 return VFW_E_NOT_FOUND;
258 static HRESULT WINAPI
259 SampleGrabber_IBaseFilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *info)
261 SG_Impl *This = impl_from_IBaseFilter(iface);
262 TRACE("(%p)->(%p)\n", This, info);
265 if (This->info.pGraph)
266 IFilterGraph_AddRef(This->info.pGraph);
272 static HRESULT WINAPI
273 SampleGrabber_IBaseFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *graph, LPCWSTR name)
275 SG_Impl *This = impl_from_IBaseFilter(iface);
276 TRACE("(%p)->(%p, %s)\n", This, graph, debugstr_w(name));
277 This->info.pGraph = graph;
279 lstrcpynW(This->info.achName,name,MAX_FILTER_NAME);
284 static HRESULT WINAPI
285 SampleGrabber_IBaseFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR *vendor)
287 TRACE("(%p)\n", vendor);
290 *vendor = CoTaskMemAlloc(sizeof(vendor_name));
291 CopyMemory(*vendor, vendor_name, sizeof(vendor_name));
296 /* SampleGrabber implementation of ISampleGrabber interface */
299 static HRESULT WINAPI
300 SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber *iface, REFIID riid, void **ppvObject)
302 return SampleGrabber_query(impl_from_ISampleGrabber(iface), riid, ppvObject);
307 SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber *iface)
309 return SampleGrabber_addref(impl_from_ISampleGrabber(iface));
314 SampleGrabber_ISampleGrabber_Release(ISampleGrabber *iface)
316 return SampleGrabber_release(impl_from_ISampleGrabber(iface));
320 static HRESULT WINAPI
321 SampleGrabber_ISampleGrabber_SetOneShot(ISampleGrabber *iface, BOOL oneShot)
323 SG_Impl *This = impl_from_ISampleGrabber(iface);
324 FIXME("(%p)->(%u): stub\n", This, oneShot);
329 static HRESULT WINAPI
330 SampleGrabber_ISampleGrabber_SetMediaType(ISampleGrabber *iface, const AM_MEDIA_TYPE *type)
332 SG_Impl *This = impl_from_ISampleGrabber(iface);
333 FIXME("(%p)->(%p): stub\n", This, type);
340 static HRESULT WINAPI
341 SampleGrabber_ISampleGrabber_GetConnectedMediaType(ISampleGrabber *iface, AM_MEDIA_TYPE *type)
343 SG_Impl *This = impl_from_ISampleGrabber(iface);
344 FIXME("(%p)->(%p): stub\n", This, type);
351 static HRESULT WINAPI
352 SampleGrabber_ISampleGrabber_SetBufferSamples(ISampleGrabber *iface, BOOL bufferEm)
354 TRACE("(%u)\n", bufferEm);
356 FIXME("buffering not implemented\n");
363 static HRESULT WINAPI
364 SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber *iface, LONG *bufSize, LONG *buffer)
366 FIXME("(%p, %p): stub\n", bufSize, buffer);
373 static HRESULT WINAPI
374 SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber *iface, IMediaSample **sample)
376 /* MS doesn't implement it either, noone should call it */
377 WARN("(%p): not implemented\n", sample);
382 static HRESULT WINAPI
383 SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber *iface, ISampleGrabberCB *cb, LONG whichMethod)
385 SG_Impl *This = impl_from_ISampleGrabber(iface);
386 FIXME("(%p)->(%p, %u): stub\n", This, cb, whichMethod);
391 /* SampleGrabber vtables and constructor */
393 static const IBaseFilterVtbl IBaseFilter_VTable =
395 SampleGrabber_IBaseFilter_QueryInterface,
396 SampleGrabber_IBaseFilter_AddRef,
397 SampleGrabber_IBaseFilter_Release,
398 SampleGrabber_IBaseFilter_GetClassID,
399 SampleGrabber_IBaseFilter_Stop,
400 SampleGrabber_IBaseFilter_Pause,
401 SampleGrabber_IBaseFilter_Run,
402 SampleGrabber_IBaseFilter_GetState,
403 SampleGrabber_IBaseFilter_SetSyncSource,
404 SampleGrabber_IBaseFilter_GetSyncSource,
405 SampleGrabber_IBaseFilter_EnumPins,
406 SampleGrabber_IBaseFilter_FindPin,
407 SampleGrabber_IBaseFilter_QueryFilterInfo,
408 SampleGrabber_IBaseFilter_JoinFilterGraph,
409 SampleGrabber_IBaseFilter_QueryVendorInfo,
412 static const ISampleGrabberVtbl ISampleGrabber_VTable =
414 SampleGrabber_ISampleGrabber_QueryInterface,
415 SampleGrabber_ISampleGrabber_AddRef,
416 SampleGrabber_ISampleGrabber_Release,
417 SampleGrabber_ISampleGrabber_SetOneShot,
418 SampleGrabber_ISampleGrabber_SetMediaType,
419 SampleGrabber_ISampleGrabber_GetConnectedMediaType,
420 SampleGrabber_ISampleGrabber_SetBufferSamples,
421 SampleGrabber_ISampleGrabber_GetCurrentBuffer,
422 SampleGrabber_ISampleGrabber_GetCurrentSample,
423 SampleGrabber_ISampleGrabber_SetCallback,
426 HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
430 TRACE("(%p,%p)\n", ppv, pUnkOuter);
433 return CLASS_E_NOAGGREGATION;
435 obj = CoTaskMemAlloc(sizeof(SG_Impl));
438 return E_OUTOFMEMORY;
440 ZeroMemory(obj, sizeof(SG_Impl));
443 obj->IBaseFilter_Vtbl = &IBaseFilter_VTable;
444 obj->ISampleGrabber_Vtbl = &ISampleGrabber_VTable;
445 obj->info.achName[0] = 0;
446 obj->info.pGraph = NULL;
447 obj->state = State_Stopped;
448 obj->allocator = NULL;
449 obj->refClock = NULL;