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
;