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 };
36 static WCHAR
const pin_in_name
[] = { 'I', 'n', 0 };
37 static WCHAR
const pin_out_name
[] = { 'O', 'u', 't', 0 };
39 static IEnumPins
*pinsenum_create(IBaseFilter
*filter
, IPin
**pins
, ULONG pinCount
);
40 static IEnumMediaTypes
*mediaenum_create(const AM_MEDIA_TYPE
*mtype
);
42 /* Fixed pins enumerator, holds filter referenced */
43 typedef struct _PE_Impl
{
53 /* IEnumPins interface implementation */
57 Fixed_IEnumPins_AddRef(IEnumPins
*iface
)
59 PE_Impl
*This
= (PE_Impl
*)iface
;
60 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
61 TRACE("(%p) new ref = %u\n", This
, refCount
);
67 Fixed_IEnumPins_Release(IEnumPins
*iface
)
69 PE_Impl
*This
= (PE_Impl
*)iface
;
70 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
71 TRACE("(%p) new ref = %u\n", This
, refCount
);
74 IBaseFilter_Release(This
->filter
);
83 Fixed_IEnumPins_QueryInterface(IEnumPins
*iface
, REFIID riid
, void **ppvObject
)
85 PE_Impl
*This
= (PE_Impl
*)iface
;
86 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
88 if (IsEqualIID(riid
, &IID_IUnknown
) ||
89 IsEqualIID(riid
, &IID_IEnumPins
)) {
90 Fixed_IEnumPins_AddRef(iface
);
91 *ppvObject
= &(This
->pins
);
95 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppvObject
);
100 static HRESULT WINAPI
101 Fixed_IEnumPins_Next(IEnumPins
*iface
, ULONG nPins
, IPin
**pins
, ULONG
*fetched
)
103 PE_Impl
*This
= (PE_Impl
*)iface
;
105 TRACE("(%p)->(%u, %p, %p) index = %u\n", This
, nPins
, pins
, fetched
, This
->index
);
108 if (!pins
|| ((nPins
!= 1) && !fetched
))
110 while ((count
< nPins
) && (This
->index
< This
->numPins
)) {
111 IPin
*pin
= This
->pins
[This
->index
++];
117 return (count
== nPins
) ? S_OK
: S_FALSE
;
121 static HRESULT WINAPI
122 Fixed_IEnumPins_Skip(IEnumPins
*iface
, ULONG nPins
)
124 PE_Impl
*This
= (PE_Impl
*)iface
;
125 TRACE("(%p)->(%u) index = %u\n", This
, nPins
, This
->index
);
126 nPins
+= This
->index
;
127 if (nPins
>= This
->numPins
) {
128 This
->index
= This
->numPins
;
136 static HRESULT WINAPI
137 Fixed_IEnumPins_Reset(IEnumPins
*iface
)
139 PE_Impl
*This
= (PE_Impl
*)iface
;
140 TRACE("(%p)->() index = %u\n", This
, This
->index
);
146 static HRESULT WINAPI
147 Fixed_IEnumPins_Clone(IEnumPins
*iface
, IEnumPins
**pins
)
149 PE_Impl
*This
= (PE_Impl
*)iface
;
150 TRACE("(%p)->(%p) index = %u\n", This
, pins
, This
->index
);
153 *pins
= pinsenum_create(This
->filter
, This
->pins
, This
->numPins
);
155 return E_OUTOFMEMORY
;
156 ((PE_Impl
*)*pins
)->index
= This
->index
;
161 /* Virtual tables and constructor */
163 static const IEnumPinsVtbl IEnumPins_VTable
=
165 Fixed_IEnumPins_QueryInterface
,
166 Fixed_IEnumPins_AddRef
,
167 Fixed_IEnumPins_Release
,
168 Fixed_IEnumPins_Next
,
169 Fixed_IEnumPins_Skip
,
170 Fixed_IEnumPins_Reset
,
171 Fixed_IEnumPins_Clone
,
174 static IEnumPins
*pinsenum_create(IBaseFilter
*filter
, IPin
**pins
, ULONG pinCount
)
176 ULONG len
= sizeof(PE_Impl
) + (pinCount
* sizeof(IPin
*));
177 PE_Impl
*obj
= CoTaskMemAlloc(len
);
180 ZeroMemory(obj
, len
);
181 obj
->pe
.lpVtbl
= &IEnumPins_VTable
;
183 obj
->filter
= filter
;
184 obj
->numPins
= pinCount
;
186 for (i
=0; i
<pinCount
; i
++)
187 obj
->pins
[i
] = pins
[i
];
188 IBaseFilter_AddRef(filter
);
194 /* Single media type enumerator */
195 typedef struct _ME_Impl
{
203 /* IEnumMediaTypes interface implementation */
207 Single_IEnumMediaTypes_AddRef(IEnumMediaTypes
*iface
)
209 ME_Impl
*This
= (ME_Impl
*)iface
;
210 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
211 TRACE("(%p) new ref = %u\n", This
, refCount
);
217 Single_IEnumMediaTypes_Release(IEnumMediaTypes
*iface
)
219 ME_Impl
*This
= (ME_Impl
*)iface
;
220 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
221 TRACE("(%p) new ref = %u\n", This
, refCount
);
224 if (This
->mtype
.pbFormat
)
225 CoTaskMemFree(This
->mtype
.pbFormat
);
233 static HRESULT WINAPI
234 Single_IEnumMediaTypes_QueryInterface(IEnumMediaTypes
*iface
, REFIID riid
, void **ppvObject
)
236 ME_Impl
*This
= (ME_Impl
*)iface
;
237 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
239 if (IsEqualIID(riid
, &IID_IUnknown
) ||
240 IsEqualIID(riid
, &IID_IEnumMediaTypes
)) {
241 Single_IEnumMediaTypes_AddRef(iface
);
242 *ppvObject
= &(This
->me
);
246 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppvObject
);
247 return E_NOINTERFACE
;
250 /* IEnumMediaTypes */
251 static HRESULT WINAPI
252 Single_IEnumMediaTypes_Next(IEnumMediaTypes
*iface
, ULONG nTypes
, AM_MEDIA_TYPE
**types
, ULONG
*fetched
)
254 ME_Impl
*This
= (ME_Impl
*)iface
;
256 TRACE("(%p)->(%u, %p, %p)\n", This
, nTypes
, types
, fetched
);
259 if (!types
|| ((nTypes
!= 1) && !fetched
))
261 if (!This
->past
&& !IsEqualGUID(&This
->mtype
.majortype
,&GUID_NULL
)) {
262 AM_MEDIA_TYPE
*mtype
= CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
263 *mtype
= This
->mtype
;
264 if (mtype
->cbFormat
) {
265 mtype
->pbFormat
= CoTaskMemAlloc(mtype
->cbFormat
);
266 CopyMemory(mtype
->pbFormat
, This
->mtype
.pbFormat
, mtype
->cbFormat
);
274 return (count
== nTypes
) ? S_OK
: S_FALSE
;
277 /* IEnumMediaTypes */
278 static HRESULT WINAPI
279 Single_IEnumMediaTypes_Skip(IEnumMediaTypes
*iface
, ULONG nTypes
)
281 ME_Impl
*This
= (ME_Impl
*)iface
;
282 TRACE("(%p)->(%u)\n", This
, nTypes
);
285 return This
->past
? S_FALSE
: S_OK
;
288 /* IEnumMediaTypes */
289 static HRESULT WINAPI
290 Single_IEnumMediaTypes_Reset(IEnumMediaTypes
*iface
)
292 ME_Impl
*This
= (ME_Impl
*)iface
;
293 TRACE("(%p)->()\n", This
);
298 /* IEnumMediaTypes */
299 static HRESULT WINAPI
300 Single_IEnumMediaTypes_Clone(IEnumMediaTypes
*iface
, IEnumMediaTypes
**me
)
302 ME_Impl
*This
= (ME_Impl
*)iface
;
303 TRACE("(%p)->(%p)\n", This
, me
);
306 *me
= mediaenum_create(&This
->mtype
);
308 return E_OUTOFMEMORY
;
309 ((ME_Impl
*)*me
)->past
= This
->past
;
314 /* Virtual tables and constructor */
316 static const IEnumMediaTypesVtbl IEnumMediaTypes_VTable
=
318 Single_IEnumMediaTypes_QueryInterface
,
319 Single_IEnumMediaTypes_AddRef
,
320 Single_IEnumMediaTypes_Release
,
321 Single_IEnumMediaTypes_Next
,
322 Single_IEnumMediaTypes_Skip
,
323 Single_IEnumMediaTypes_Reset
,
324 Single_IEnumMediaTypes_Clone
,
327 static IEnumMediaTypes
*mediaenum_create(const AM_MEDIA_TYPE
*mtype
)
329 ME_Impl
*obj
= CoTaskMemAlloc(sizeof(ME_Impl
));
331 ZeroMemory(obj
, sizeof(ME_Impl
));
332 obj
->me
.lpVtbl
= &IEnumMediaTypes_VTable
;
337 obj
->mtype
.pUnk
= NULL
;
338 if (mtype
->cbFormat
) {
339 obj
->mtype
.pbFormat
= CoTaskMemAlloc(mtype
->cbFormat
);
340 CopyMemory(obj
->mtype
.pbFormat
, mtype
->pbFormat
, mtype
->cbFormat
);
343 obj
->mtype
.pbFormat
= NULL
;
346 obj
->mtype
.majortype
= GUID_NULL
;
352 /* Sample Grabber pin implementation */
353 typedef struct _SG_Pin
{
354 const IPinVtbl
* lpVtbl
;
361 /* Sample Grabber filter implementation */
362 typedef struct _SG_Impl
{
363 const IBaseFilterVtbl
* IBaseFilter_Vtbl
;
364 const ISampleGrabberVtbl
* ISampleGrabber_Vtbl
;
365 const IMemInputPinVtbl
* IMemInputPin_Vtbl
;
366 /* TODO: IMediaPosition, IMediaSeeking, IQualityControl */
368 CRITICAL_SECTION critSect
;
374 IMemAllocator
*allocator
;
375 IReferenceClock
*refClock
;
376 IMemInputPin
*memOutput
;
377 ISampleGrabberCB
*grabberIface
;
390 /* Get the SampleGrabber implementation This pointer from various interface pointers */
391 static inline SG_Impl
*impl_from_IBaseFilter(IBaseFilter
*iface
)
393 return (SG_Impl
*)((char*)iface
- FIELD_OFFSET(SG_Impl
, IBaseFilter_Vtbl
));
396 static inline SG_Impl
*impl_from_ISampleGrabber(ISampleGrabber
*iface
)
398 return (SG_Impl
*)((char*)iface
- FIELD_OFFSET(SG_Impl
, ISampleGrabber_Vtbl
));
401 static inline SG_Impl
*impl_from_IMemInputPin(IMemInputPin
*iface
)
403 return (SG_Impl
*)((char*)iface
- FIELD_OFFSET(SG_Impl
, IMemInputPin_Vtbl
));
407 /* Cleanup at end of life */
408 static void SampleGrabber_cleanup(SG_Impl
*This
)
410 TRACE("(%p)\n", This
);
411 if (This
->info
.pGraph
)
412 WARN("(%p) still joined to filter graph %p\n", This
, This
->info
.pGraph
);
414 IMemAllocator_Release(This
->allocator
);
416 IReferenceClock_Release(This
->refClock
);
418 IMemInputPin_Release(This
->memOutput
);
419 if (This
->grabberIface
)
420 ISampleGrabberCB_Release(This
->grabberIface
);
421 if (This
->mtype
.pbFormat
)
422 CoTaskMemFree(This
->mtype
.pbFormat
);
423 if (This
->bufferData
)
424 CoTaskMemFree(This
->bufferData
);
425 This
->critSect
.DebugInfo
->Spare
[0] = 0;
426 DeleteCriticalSection(&This
->critSect
);
429 /* Common helper AddRef called from all interfaces */
430 static ULONG
SampleGrabber_addref(SG_Impl
*This
)
432 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
433 TRACE("(%p) new ref = %u\n", This
, refCount
);
437 /* Common helper Release called from all interfaces */
438 static ULONG
SampleGrabber_release(SG_Impl
*This
)
440 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
441 TRACE("(%p) new ref = %u\n", This
, refCount
);
444 SampleGrabber_cleanup(This
);
451 /* Common helper QueryInterface called from all interfaces */
452 static HRESULT
SampleGrabber_query(SG_Impl
*This
, REFIID riid
, void **ppvObject
)
454 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
456 if (IsEqualIID(riid
, &IID_IUnknown
) ||
457 IsEqualIID(riid
, &IID_IPersist
) ||
458 IsEqualIID(riid
, &IID_IMediaFilter
) ||
459 IsEqualIID(riid
, &IID_IBaseFilter
)) {
460 SampleGrabber_addref(This
);
461 *ppvObject
= &(This
->IBaseFilter_Vtbl
);
464 else if (IsEqualIID(riid
, &IID_ISampleGrabber
)) {
465 SampleGrabber_addref(This
);
466 *ppvObject
= &(This
->ISampleGrabber_Vtbl
);
469 else if (IsEqualIID(riid
, &IID_IMemInputPin
)) {
470 SampleGrabber_addref(This
);
471 *ppvObject
= &(This
->IMemInputPin_Vtbl
);
474 else if (IsEqualIID(riid
, &IID_IMediaPosition
))
475 FIXME("IMediaPosition not implemented\n");
476 else if (IsEqualIID(riid
, &IID_IMediaSeeking
))
477 FIXME("IMediaSeeking not implemented\n");
478 else if (IsEqualIID(riid
, &IID_IQualityControl
))
479 FIXME("IQualityControl not implemented\n");
481 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppvObject
);
482 return E_NOINTERFACE
;
485 /* Helper that buffers data and/or calls installed sample callbacks */
486 static void SampleGrabber_callback(SG_Impl
*This
, IMediaSample
*sample
)
489 REFERENCE_TIME tStart
, tEnd
;
490 if (This
->bufferLen
>= 0) {
492 LONG size
= IMediaSample_GetActualDataLength(sample
);
493 if (size
>= 0 && SUCCEEDED(IMediaSample_GetPointer(sample
, &data
))) {
496 EnterCriticalSection(&This
->critSect
);
497 if (This
->bufferLen
!= size
) {
498 if (This
->bufferData
)
499 CoTaskMemFree(This
->bufferData
);
500 This
->bufferData
= size
? CoTaskMemAlloc(size
) : NULL
;
501 This
->bufferLen
= size
;
504 CopyMemory(This
->bufferData
, data
, size
);
505 LeaveCriticalSection(&This
->critSect
);
508 if (!This
->grabberIface
)
510 if (SUCCEEDED(IMediaSample_GetTime(sample
, &tStart
, &tEnd
)))
511 time
= 1e-7 * tStart
;
512 switch (This
->grabberMethod
) {
515 ULONG ref
= IMediaSample_AddRef(sample
);
516 ISampleGrabberCB_SampleCB(This
->grabberIface
, time
, sample
);
517 ref
= IMediaSample_Release(sample
) + 1 - ref
;
520 ERR("(%p) Callback referenced sample %p by %u\n", This
, sample
, ref
);
521 /* ugly as hell but some apps are sooo buggy */
523 IMediaSample_Release(sample
);
530 LONG size
= IMediaSample_GetActualDataLength(sample
);
531 if (size
&& SUCCEEDED(IMediaSample_GetPointer(sample
, &data
)) && data
)
532 ISampleGrabberCB_BufferCB(This
->grabberIface
, time
, data
, size
);
538 FIXME("unsupported method %d\n", This
->grabberMethod
);
539 /* do not bother us again */
540 This
->grabberMethod
= -1;
545 /* SampleGrabber implementation of IBaseFilter interface */
548 static HRESULT WINAPI
549 SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter
*iface
, REFIID riid
, void **ppvObject
)
551 return SampleGrabber_query(impl_from_IBaseFilter(iface
), riid
, ppvObject
);
556 SampleGrabber_IBaseFilter_AddRef(IBaseFilter
*iface
)
558 return SampleGrabber_addref(impl_from_IBaseFilter(iface
));
563 SampleGrabber_IBaseFilter_Release(IBaseFilter
*iface
)
565 return SampleGrabber_release(impl_from_IBaseFilter(iface
));
569 static HRESULT WINAPI
570 SampleGrabber_IBaseFilter_GetClassID(IBaseFilter
*iface
, CLSID
*pClassID
)
572 TRACE("(%p)\n", pClassID
);
575 *pClassID
= CLSID_SampleGrabber
;
580 static HRESULT WINAPI
581 SampleGrabber_IBaseFilter_Stop(IBaseFilter
*iface
)
583 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
584 TRACE("(%p)\n", This
);
585 This
->state
= State_Stopped
;
590 static HRESULT WINAPI
591 SampleGrabber_IBaseFilter_Pause(IBaseFilter
*iface
)
593 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
594 TRACE("(%p)\n", This
);
595 This
->state
= State_Paused
;
600 static HRESULT WINAPI
601 SampleGrabber_IBaseFilter_Run(IBaseFilter
*iface
, REFERENCE_TIME tStart
)
603 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
604 TRACE("(%p)\n", This
);
605 This
->state
= State_Running
;
610 static HRESULT WINAPI
611 SampleGrabber_IBaseFilter_GetState(IBaseFilter
*iface
, DWORD msTout
, FILTER_STATE
*state
)
613 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
614 TRACE("(%p)->(%u, %p)\n", This
, msTout
, state
);
617 *state
= This
->state
;
622 static HRESULT WINAPI
623 SampleGrabber_IBaseFilter_SetSyncSource(IBaseFilter
*iface
, IReferenceClock
*clock
)
625 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
626 TRACE("(%p)->(%p)\n", This
, clock
);
627 if (clock
!= This
->refClock
)
630 IReferenceClock_AddRef(clock
);
632 IReferenceClock_Release(This
->refClock
);
633 This
->refClock
= clock
;
639 static HRESULT WINAPI
640 SampleGrabber_IBaseFilter_GetSyncSource(IBaseFilter
*iface
, IReferenceClock
**clock
)
642 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
643 TRACE("(%p)->(%p)\n", This
, clock
);
647 IReferenceClock_AddRef(This
->refClock
);
648 *clock
= This
->refClock
;
653 static HRESULT WINAPI
654 SampleGrabber_IBaseFilter_EnumPins(IBaseFilter
*iface
, IEnumPins
**pins
)
656 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
658 TRACE("(%p)->(%p)\n", This
, pins
);
661 pin
[0] = (IPin
*)&This
->pin_in
.lpVtbl
;
662 pin
[1] = (IPin
*)&This
->pin_out
.lpVtbl
;
663 *pins
= pinsenum_create(iface
, pin
, 2);
664 return *pins
? S_OK
: E_OUTOFMEMORY
;
668 static HRESULT WINAPI
669 SampleGrabber_IBaseFilter_FindPin(IBaseFilter
*iface
, LPCWSTR id
, IPin
**pin
)
671 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
672 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(id
), pin
);
675 if (!lstrcmpiW(id
,pin_in_name
))
677 SampleGrabber_addref(This
);
678 *pin
= (IPin
*)&(This
->pin_in
.lpVtbl
);
681 else if (!lstrcmpiW(id
,pin_out_name
))
683 SampleGrabber_addref(This
);
684 *pin
= (IPin
*)&(This
->pin_out
.lpVtbl
);
688 return VFW_E_NOT_FOUND
;
692 static HRESULT WINAPI
693 SampleGrabber_IBaseFilter_QueryFilterInfo(IBaseFilter
*iface
, FILTER_INFO
*info
)
695 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
696 TRACE("(%p)->(%p)\n", This
, info
);
699 if (This
->info
.pGraph
)
700 IFilterGraph_AddRef(This
->info
.pGraph
);
706 static HRESULT WINAPI
707 SampleGrabber_IBaseFilter_JoinFilterGraph(IBaseFilter
*iface
, IFilterGraph
*graph
, LPCWSTR name
)
709 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
710 TRACE("(%p)->(%p, %s)\n", This
, graph
, debugstr_w(name
));
711 This
->info
.pGraph
= graph
;
713 lstrcpynW(This
->info
.achName
,name
,MAX_FILTER_NAME
);
714 This
->oneShot
= OneShot_None
;
719 static HRESULT WINAPI
720 SampleGrabber_IBaseFilter_QueryVendorInfo(IBaseFilter
*iface
, LPWSTR
*vendor
)
722 TRACE("(%p)\n", vendor
);
725 *vendor
= CoTaskMemAlloc(sizeof(vendor_name
));
726 CopyMemory(*vendor
, vendor_name
, sizeof(vendor_name
));
731 /* SampleGrabber implementation of ISampleGrabber interface */
734 static HRESULT WINAPI
735 SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber
*iface
, REFIID riid
, void **ppvObject
)
737 return SampleGrabber_query(impl_from_ISampleGrabber(iface
), riid
, ppvObject
);
742 SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber
*iface
)
744 return SampleGrabber_addref(impl_from_ISampleGrabber(iface
));
749 SampleGrabber_ISampleGrabber_Release(ISampleGrabber
*iface
)
751 return SampleGrabber_release(impl_from_ISampleGrabber(iface
));
755 static HRESULT WINAPI
756 SampleGrabber_ISampleGrabber_SetOneShot(ISampleGrabber
*iface
, BOOL oneShot
)
758 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
759 TRACE("(%p)->(%u)\n", This
, oneShot
);
760 This
->oneShot
= oneShot
? OneShot_Wait
: OneShot_None
;
765 static HRESULT WINAPI
766 SampleGrabber_ISampleGrabber_SetMediaType(ISampleGrabber
*iface
, const AM_MEDIA_TYPE
*type
)
768 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
769 TRACE("(%p)->(%p)\n", This
, type
);
772 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
773 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
775 debugstr_guid(&type
->formattype
), type
->cbFormat
);
776 if (This
->mtype
.pbFormat
)
777 CoTaskMemFree(This
->mtype
.pbFormat
);
779 This
->mtype
.pUnk
= NULL
;
780 if (type
->cbFormat
) {
781 This
->mtype
.pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
782 CopyMemory(This
->mtype
.pbFormat
, type
->pbFormat
, type
->cbFormat
);
785 This
->mtype
.pbFormat
= NULL
;
790 static HRESULT WINAPI
791 SampleGrabber_ISampleGrabber_GetConnectedMediaType(ISampleGrabber
*iface
, AM_MEDIA_TYPE
*type
)
793 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
794 TRACE("(%p)->(%p)\n", This
, type
);
797 if (!This
->pin_in
.pair
)
798 return VFW_E_NOT_CONNECTED
;
800 if (type
->cbFormat
) {
801 type
->pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
802 CopyMemory(type
->pbFormat
, This
->mtype
.pbFormat
, type
->cbFormat
);
808 static HRESULT WINAPI
809 SampleGrabber_ISampleGrabber_SetBufferSamples(ISampleGrabber
*iface
, BOOL bufferEm
)
811 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
812 TRACE("(%p)->(%u)\n", This
, bufferEm
);
813 EnterCriticalSection(&This
->critSect
);
815 if (This
->bufferLen
< 0)
819 This
->bufferLen
= -1;
820 LeaveCriticalSection(&This
->critSect
);
825 static HRESULT WINAPI
826 SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber
*iface
, LONG
*bufSize
, LONG
*buffer
)
828 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
830 TRACE("(%p)->(%p, %p)\n", This
, bufSize
, buffer
);
833 EnterCriticalSection(&This
->critSect
);
834 if (!This
->pin_in
.pair
)
835 ret
= VFW_E_NOT_CONNECTED
;
836 else if (This
->bufferLen
< 0)
838 else if (This
->bufferLen
== 0)
839 ret
= VFW_E_WRONG_STATE
;
842 if (*bufSize
>= This
->bufferLen
)
843 CopyMemory(buffer
, This
->bufferData
, This
->bufferLen
);
847 *bufSize
= This
->bufferLen
;
849 LeaveCriticalSection(&This
->critSect
);
854 static HRESULT WINAPI
855 SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber
*iface
, IMediaSample
**sample
)
857 /* MS doesn't implement it either, no one should call it */
858 WARN("(%p): not implemented\n", sample
);
863 static HRESULT WINAPI
864 SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber
*iface
, ISampleGrabberCB
*cb
, LONG whichMethod
)
866 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
867 TRACE("(%p)->(%p, %u)\n", This
, cb
, whichMethod
);
868 if (This
->grabberIface
)
869 ISampleGrabberCB_Release(This
->grabberIface
);
870 This
->grabberIface
= cb
;
871 This
->grabberMethod
= whichMethod
;
873 ISampleGrabberCB_AddRef(cb
);
878 /* SampleGrabber implementation of IMemInputPin interface */
881 static HRESULT WINAPI
882 SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin
*iface
, REFIID riid
, void **ppvObject
)
884 return SampleGrabber_query(impl_from_IMemInputPin(iface
), riid
, ppvObject
);
889 SampleGrabber_IMemInputPin_AddRef(IMemInputPin
*iface
)
891 return SampleGrabber_addref(impl_from_IMemInputPin(iface
));
896 SampleGrabber_IMemInputPin_Release(IMemInputPin
*iface
)
898 return SampleGrabber_release(impl_from_IMemInputPin(iface
));
902 static HRESULT WINAPI
903 SampleGrabber_IMemInputPin_GetAllocator(IMemInputPin
*iface
, IMemAllocator
**allocator
)
905 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
906 TRACE("(%p)->(%p) allocator = %p\n", This
, allocator
, This
->allocator
);
909 *allocator
= This
->allocator
;
911 return VFW_E_NO_ALLOCATOR
;
912 IMemAllocator_AddRef(*allocator
);
917 static HRESULT WINAPI
918 SampleGrabber_IMemInputPin_NotifyAllocator(IMemInputPin
*iface
, IMemAllocator
*allocator
, BOOL readOnly
)
920 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
921 TRACE("(%p)->(%p, %u) allocator = %p\n", This
, allocator
, readOnly
, This
->allocator
);
922 if (This
->allocator
== allocator
)
925 IMemAllocator_Release(This
->allocator
);
926 This
->allocator
= allocator
;
928 IMemAllocator_AddRef(allocator
);
933 static HRESULT WINAPI
934 SampleGrabber_IMemInputPin_GetAllocatorRequirements(IMemInputPin
*iface
, ALLOCATOR_PROPERTIES
*props
)
936 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
937 FIXME("(%p)->(%p): semi-stub\n", This
, props
);
940 return This
->memOutput
? IMemInputPin_GetAllocatorRequirements(This
->memOutput
, props
) : E_NOTIMPL
;
944 static HRESULT WINAPI
945 SampleGrabber_IMemInputPin_Receive(IMemInputPin
*iface
, IMediaSample
*sample
)
947 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
949 TRACE("(%p)->(%p) output = %p, grabber = %p\n", This
, sample
, This
->memOutput
, This
->grabberIface
);
952 if ((This
->state
!= State_Running
) || (This
->oneShot
== OneShot_Past
))
954 SampleGrabber_callback(This
, sample
);
955 hr
= This
->memOutput
? IMemInputPin_Receive(This
->memOutput
, sample
) : S_OK
;
956 if (This
->oneShot
== OneShot_Wait
) {
957 This
->oneShot
= OneShot_Past
;
959 if (This
->pin_out
.pair
)
960 IPin_EndOfStream(This
->pin_out
.pair
);
966 static HRESULT WINAPI
967 SampleGrabber_IMemInputPin_ReceiveMultiple(IMemInputPin
*iface
, IMediaSample
**samples
, LONG nSamples
, LONG
*nProcessed
)
969 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
971 TRACE("(%p)->(%p, %u, %p) output = %p, grabber = %p\n", This
, samples
, nSamples
, nProcessed
, This
->memOutput
, This
->grabberIface
);
972 if (!samples
|| !nProcessed
)
974 if ((This
->state
!= State_Running
) || (This
->oneShot
== OneShot_Past
))
976 for (idx
= 0; idx
< nSamples
; idx
++)
977 SampleGrabber_callback(This
, samples
[idx
]);
978 return This
->memOutput
? IMemInputPin_ReceiveMultiple(This
->memOutput
, samples
, nSamples
, nProcessed
) : S_OK
;
982 static HRESULT WINAPI
983 SampleGrabber_IMemInputPin_ReceiveCanBlock(IMemInputPin
*iface
)
985 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
986 TRACE("(%p)\n", This
);
987 return This
->memOutput
? IMemInputPin_ReceiveCanBlock(This
->memOutput
) : S_OK
;
991 /* SampleGrabber member pin implementation */
995 SampleGrabber_IPin_AddRef(IPin
*iface
)
997 return SampleGrabber_addref(((SG_Pin
*)iface
)->sg
);
1002 SampleGrabber_IPin_Release(IPin
*iface
)
1004 return SampleGrabber_release(((SG_Pin
*)iface
)->sg
);
1008 static HRESULT WINAPI
1009 SampleGrabber_IPin_QueryInterface(IPin
*iface
, REFIID riid
, void **ppvObject
)
1011 SG_Pin
*This
= (SG_Pin
*)iface
;
1012 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1014 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1015 IsEqualIID(riid
, &IID_IPin
)) {
1016 SampleGrabber_addref(This
->sg
);
1020 else if (IsEqualIID(riid
, &IID_IMemInputPin
)) {
1021 SampleGrabber_addref(This
->sg
);
1022 *ppvObject
= &(This
->sg
->IMemInputPin_Vtbl
);
1026 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppvObject
);
1027 return E_NOINTERFACE
;
1030 /* IPin - input pin */
1031 static HRESULT WINAPI
1032 SampleGrabber_In_IPin_Connect(IPin
*iface
, IPin
*receiver
, const AM_MEDIA_TYPE
*mtype
)
1034 WARN("(%p, %p): unexpected\n", receiver
, mtype
);
1035 return E_UNEXPECTED
;
1038 /* IPin - output pin */
1039 static HRESULT WINAPI
1040 SampleGrabber_Out_IPin_Connect(IPin
*iface
, IPin
*receiver
, const AM_MEDIA_TYPE
*type
)
1042 SG_Pin
*This
= (SG_Pin
*)iface
;
1044 TRACE("(%p)->(%p, %p)\n", This
, receiver
, type
);
1048 return VFW_E_ALREADY_CONNECTED
;
1049 if (This
->sg
->state
!= State_Stopped
)
1050 return VFW_E_NOT_STOPPED
;
1052 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
1053 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
1055 debugstr_guid(&type
->formattype
), type
->cbFormat
);
1056 if (!IsEqualGUID(&This
->sg
->mtype
.majortype
,&GUID_NULL
) &&
1057 !IsEqualGUID(&This
->sg
->mtype
.majortype
,&type
->majortype
))
1058 return VFW_E_TYPE_NOT_ACCEPTED
;
1059 if (!IsEqualGUID(&This
->sg
->mtype
.subtype
,&MEDIASUBTYPE_None
) &&
1060 !IsEqualGUID(&This
->sg
->mtype
.subtype
,&type
->subtype
))
1061 return VFW_E_TYPE_NOT_ACCEPTED
;
1062 if (!IsEqualGUID(&This
->sg
->mtype
.formattype
,&GUID_NULL
) &&
1063 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&FORMAT_None
) &&
1064 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&type
->formattype
))
1065 return VFW_E_TYPE_NOT_ACCEPTED
;
1068 type
= &This
->sg
->mtype
;
1069 if (!IsEqualGUID(&type
->formattype
, &FORMAT_None
) &&
1070 !IsEqualGUID(&type
->formattype
, &GUID_NULL
) &&
1072 return VFW_E_TYPE_NOT_ACCEPTED
;
1073 hr
= IPin_ReceiveConnection(receiver
,(IPin
*)&This
->lpVtbl
,type
);
1076 This
->pair
= receiver
;
1077 if (This
->sg
->memOutput
) {
1078 IMemInputPin_Release(This
->sg
->memOutput
);
1079 This
->sg
->memOutput
= NULL
;
1081 IPin_QueryInterface(receiver
,&IID_IMemInputPin
,(void **)&(This
->sg
->memOutput
));
1082 TRACE("(%p) Accepted IPin %p, IMemInputPin %p\n", This
, receiver
, This
->sg
->memOutput
);
1086 /* IPin - input pin */
1087 static HRESULT WINAPI
1088 SampleGrabber_In_IPin_ReceiveConnection(IPin
*iface
, IPin
*connector
, const AM_MEDIA_TYPE
*type
)
1090 SG_Pin
*This
= (SG_Pin
*)iface
;
1091 TRACE("(%p)->(%p, %p)\n", This
, connector
, type
);
1095 return VFW_E_ALREADY_CONNECTED
;
1096 if (This
->sg
->state
!= State_Stopped
)
1097 return VFW_E_NOT_STOPPED
;
1099 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
1100 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
1102 debugstr_guid(&type
->formattype
), type
->cbFormat
);
1103 if (!IsEqualGUID(&type
->formattype
, &FORMAT_None
) &&
1104 !IsEqualGUID(&type
->formattype
, &GUID_NULL
) &&
1106 return VFW_E_INVALIDMEDIATYPE
;
1107 if (!IsEqualGUID(&This
->sg
->mtype
.majortype
,&GUID_NULL
) &&
1108 !IsEqualGUID(&This
->sg
->mtype
.majortype
,&type
->majortype
))
1109 return VFW_E_TYPE_NOT_ACCEPTED
;
1110 if (!IsEqualGUID(&This
->sg
->mtype
.subtype
,&MEDIASUBTYPE_None
) &&
1111 !IsEqualGUID(&This
->sg
->mtype
.subtype
,&type
->subtype
))
1112 return VFW_E_TYPE_NOT_ACCEPTED
;
1113 if (!IsEqualGUID(&This
->sg
->mtype
.formattype
,&GUID_NULL
) &&
1114 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&FORMAT_None
) &&
1115 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&type
->formattype
))
1116 return VFW_E_TYPE_NOT_ACCEPTED
;
1117 if (This
->sg
->mtype
.pbFormat
)
1118 CoTaskMemFree(This
->sg
->mtype
.pbFormat
);
1119 This
->sg
->mtype
= *type
;
1120 This
->sg
->mtype
.pUnk
= NULL
;
1121 if (type
->cbFormat
) {
1122 This
->sg
->mtype
.pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
1123 CopyMemory(This
->sg
->mtype
.pbFormat
, type
->pbFormat
, type
->cbFormat
);
1126 This
->sg
->mtype
.pbFormat
= NULL
;
1128 This
->pair
= connector
;
1129 TRACE("(%p) Accepted IPin %p\n", This
, connector
);
1133 /* IPin - output pin */
1134 static HRESULT WINAPI
1135 SampleGrabber_Out_IPin_ReceiveConnection(IPin
*iface
, IPin
*connector
, const AM_MEDIA_TYPE
*mtype
)
1137 WARN("(%p, %p): unexpected\n", connector
, mtype
);
1138 return E_UNEXPECTED
;
1141 /* IPin - input pin */
1142 static HRESULT WINAPI
1143 SampleGrabber_In_IPin_Disconnect(IPin
*iface
)
1145 SG_Pin
*This
= (SG_Pin
*)iface
;
1146 TRACE("(%p)->() pair = %p\n", This
, This
->pair
);
1147 if (This
->sg
->state
!= State_Stopped
)
1148 return VFW_E_NOT_STOPPED
;
1156 /* IPin - output pin */
1157 static HRESULT WINAPI
1158 SampleGrabber_Out_IPin_Disconnect(IPin
*iface
)
1160 SG_Pin
*This
= (SG_Pin
*)iface
;
1161 TRACE("(%p)->() pair = %p\n", This
, This
->pair
);
1162 if (This
->sg
->state
!= State_Stopped
)
1163 return VFW_E_NOT_STOPPED
;
1166 if (This
->sg
->memOutput
) {
1167 IMemInputPin_Release(This
->sg
->memOutput
);
1168 This
->sg
->memOutput
= NULL
;
1176 static HRESULT WINAPI
1177 SampleGrabber_IPin_ConnectedTo(IPin
*iface
, IPin
**pin
)
1179 SG_Pin
*This
= (SG_Pin
*)iface
;
1180 TRACE("(%p)->(%p) pair = %p\n", This
, pin
, This
->pair
);
1188 return VFW_E_NOT_CONNECTED
;
1192 static HRESULT WINAPI
1193 SampleGrabber_IPin_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mtype
)
1195 SG_Pin
*This
= (SG_Pin
*)iface
;
1196 TRACE("(%p)->(%p)\n", This
, mtype
);
1200 return VFW_E_NOT_CONNECTED
;
1201 *mtype
= This
->sg
->mtype
;
1202 if (mtype
->cbFormat
) {
1203 mtype
->pbFormat
= CoTaskMemAlloc(mtype
->cbFormat
);
1204 CopyMemory(mtype
->pbFormat
, This
->sg
->mtype
.pbFormat
, mtype
->cbFormat
);
1210 static HRESULT WINAPI
1211 SampleGrabber_IPin_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
1213 SG_Pin
*This
= (SG_Pin
*)iface
;
1214 TRACE("(%p)->(%p)\n", This
, info
);
1217 SampleGrabber_addref(This
->sg
);
1218 info
->pFilter
= (IBaseFilter
*)This
->sg
;
1219 info
->dir
= This
->dir
;
1220 lstrcpynW(info
->achName
,This
->name
,MAX_PIN_NAME
);
1225 static HRESULT WINAPI
1226 SampleGrabber_IPin_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
1228 SG_Pin
*This
= (SG_Pin
*)iface
;
1229 TRACE("(%p)->(%p)\n", This
, dir
);
1237 static HRESULT WINAPI
1238 SampleGrabber_IPin_QueryId(IPin
*iface
, LPWSTR
*id
)
1240 SG_Pin
*This
= (SG_Pin
*)iface
;
1242 TRACE("(%p)->(%p)\n", This
, id
);
1245 len
= sizeof(WCHAR
)*(1+lstrlenW(This
->name
));
1246 *id
= CoTaskMemAlloc(len
);
1247 CopyMemory(*id
, This
->name
, len
);
1252 static HRESULT WINAPI
1253 SampleGrabber_IPin_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mtype
)
1255 TRACE("(%p)\n", mtype
);
1260 static HRESULT WINAPI
1261 SampleGrabber_IPin_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**mtypes
)
1263 SG_Pin
*This
= (SG_Pin
*)iface
;
1264 TRACE("(%p)->(%p)\n", This
, mtypes
);
1267 *mtypes
= mediaenum_create(This
->sg
->pin_in
.pair
? &This
->sg
->mtype
: NULL
);
1268 return *mtypes
? S_OK
: E_OUTOFMEMORY
;
1271 /* IPin - input pin */
1272 static HRESULT WINAPI
1273 SampleGrabber_In_IPin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*nPins
)
1275 SG_Pin
*This
= (SG_Pin
*)iface
;
1276 TRACE("(%p)->(%p, %p) size = %u\n", This
, pins
, nPins
, (nPins
? *nPins
: 0));
1282 IPin_AddRef((IPin
*)&This
->sg
->pin_out
.lpVtbl
);
1283 *pins
= (IPin
*)&This
->sg
->pin_out
.lpVtbl
;
1291 /* IPin - output pin */
1292 static HRESULT WINAPI
1293 SampleGrabber_Out_IPin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*nPins
)
1295 WARN("(%p, %p): unexpected\n", pins
, nPins
);
1302 static HRESULT WINAPI
1303 SampleGrabber_IPin_EndOfStream(IPin
*iface
)
1310 static HRESULT WINAPI
1311 SampleGrabber_IPin_BeginFlush(IPin
*iface
)
1318 static HRESULT WINAPI
1319 SampleGrabber_IPin_EndFlush(IPin
*iface
)
1326 static HRESULT WINAPI
1327 SampleGrabber_IPin_NewSegment(IPin
*iface
, REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double rate
)
1334 /* SampleGrabber vtables and constructor */
1336 static const IBaseFilterVtbl IBaseFilter_VTable
=
1338 SampleGrabber_IBaseFilter_QueryInterface
,
1339 SampleGrabber_IBaseFilter_AddRef
,
1340 SampleGrabber_IBaseFilter_Release
,
1341 SampleGrabber_IBaseFilter_GetClassID
,
1342 SampleGrabber_IBaseFilter_Stop
,
1343 SampleGrabber_IBaseFilter_Pause
,
1344 SampleGrabber_IBaseFilter_Run
,
1345 SampleGrabber_IBaseFilter_GetState
,
1346 SampleGrabber_IBaseFilter_SetSyncSource
,
1347 SampleGrabber_IBaseFilter_GetSyncSource
,
1348 SampleGrabber_IBaseFilter_EnumPins
,
1349 SampleGrabber_IBaseFilter_FindPin
,
1350 SampleGrabber_IBaseFilter_QueryFilterInfo
,
1351 SampleGrabber_IBaseFilter_JoinFilterGraph
,
1352 SampleGrabber_IBaseFilter_QueryVendorInfo
,
1355 static const ISampleGrabberVtbl ISampleGrabber_VTable
=
1357 SampleGrabber_ISampleGrabber_QueryInterface
,
1358 SampleGrabber_ISampleGrabber_AddRef
,
1359 SampleGrabber_ISampleGrabber_Release
,
1360 SampleGrabber_ISampleGrabber_SetOneShot
,
1361 SampleGrabber_ISampleGrabber_SetMediaType
,
1362 SampleGrabber_ISampleGrabber_GetConnectedMediaType
,
1363 SampleGrabber_ISampleGrabber_SetBufferSamples
,
1364 SampleGrabber_ISampleGrabber_GetCurrentBuffer
,
1365 SampleGrabber_ISampleGrabber_GetCurrentSample
,
1366 SampleGrabber_ISampleGrabber_SetCallback
,
1369 static const IMemInputPinVtbl IMemInputPin_VTable
=
1371 SampleGrabber_IMemInputPin_QueryInterface
,
1372 SampleGrabber_IMemInputPin_AddRef
,
1373 SampleGrabber_IMemInputPin_Release
,
1374 SampleGrabber_IMemInputPin_GetAllocator
,
1375 SampleGrabber_IMemInputPin_NotifyAllocator
,
1376 SampleGrabber_IMemInputPin_GetAllocatorRequirements
,
1377 SampleGrabber_IMemInputPin_Receive
,
1378 SampleGrabber_IMemInputPin_ReceiveMultiple
,
1379 SampleGrabber_IMemInputPin_ReceiveCanBlock
,
1382 static const IPinVtbl IPin_In_VTable
=
1384 SampleGrabber_IPin_QueryInterface
,
1385 SampleGrabber_IPin_AddRef
,
1386 SampleGrabber_IPin_Release
,
1387 SampleGrabber_In_IPin_Connect
,
1388 SampleGrabber_In_IPin_ReceiveConnection
,
1389 SampleGrabber_In_IPin_Disconnect
,
1390 SampleGrabber_IPin_ConnectedTo
,
1391 SampleGrabber_IPin_ConnectionMediaType
,
1392 SampleGrabber_IPin_QueryPinInfo
,
1393 SampleGrabber_IPin_QueryDirection
,
1394 SampleGrabber_IPin_QueryId
,
1395 SampleGrabber_IPin_QueryAccept
,
1396 SampleGrabber_IPin_EnumMediaTypes
,
1397 SampleGrabber_In_IPin_QueryInternalConnections
,
1398 SampleGrabber_IPin_EndOfStream
,
1399 SampleGrabber_IPin_BeginFlush
,
1400 SampleGrabber_IPin_EndFlush
,
1401 SampleGrabber_IPin_NewSegment
,
1404 static const IPinVtbl IPin_Out_VTable
=
1406 SampleGrabber_IPin_QueryInterface
,
1407 SampleGrabber_IPin_AddRef
,
1408 SampleGrabber_IPin_Release
,
1409 SampleGrabber_Out_IPin_Connect
,
1410 SampleGrabber_Out_IPin_ReceiveConnection
,
1411 SampleGrabber_Out_IPin_Disconnect
,
1412 SampleGrabber_IPin_ConnectedTo
,
1413 SampleGrabber_IPin_ConnectionMediaType
,
1414 SampleGrabber_IPin_QueryPinInfo
,
1415 SampleGrabber_IPin_QueryDirection
,
1416 SampleGrabber_IPin_QueryId
,
1417 SampleGrabber_IPin_QueryAccept
,
1418 SampleGrabber_IPin_EnumMediaTypes
,
1419 SampleGrabber_Out_IPin_QueryInternalConnections
,
1420 SampleGrabber_IPin_EndOfStream
,
1421 SampleGrabber_IPin_BeginFlush
,
1422 SampleGrabber_IPin_EndFlush
,
1423 SampleGrabber_IPin_NewSegment
,
1426 HRESULT
SampleGrabber_create(IUnknown
*pUnkOuter
, LPVOID
*ppv
)
1428 SG_Impl
* obj
= NULL
;
1430 TRACE("(%p,%p)\n", ppv
, pUnkOuter
);
1433 return CLASS_E_NOAGGREGATION
;
1435 obj
= CoTaskMemAlloc(sizeof(SG_Impl
));
1438 return E_OUTOFMEMORY
;
1440 ZeroMemory(obj
, sizeof(SG_Impl
));
1443 obj
->IBaseFilter_Vtbl
= &IBaseFilter_VTable
;
1444 obj
->ISampleGrabber_Vtbl
= &ISampleGrabber_VTable
;
1445 obj
->IMemInputPin_Vtbl
= &IMemInputPin_VTable
;
1446 obj
->pin_in
.lpVtbl
= &IPin_In_VTable
;
1447 obj
->pin_in
.dir
= PINDIR_INPUT
;
1448 obj
->pin_in
.name
= pin_in_name
;
1449 obj
->pin_in
.sg
= obj
;
1450 obj
->pin_in
.pair
= NULL
;
1451 obj
->pin_out
.lpVtbl
= &IPin_Out_VTable
;
1452 obj
->pin_out
.dir
= PINDIR_OUTPUT
;
1453 obj
->pin_out
.name
= pin_out_name
;
1454 obj
->pin_out
.sg
= obj
;
1455 obj
->pin_out
.pair
= NULL
;
1456 InitializeCriticalSection(&obj
->critSect
);
1457 obj
->critSect
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": SG_Impl.critSect");
1458 obj
->info
.achName
[0] = 0;
1459 obj
->info
.pGraph
= NULL
;
1460 obj
->state
= State_Stopped
;
1461 obj
->mtype
.majortype
= GUID_NULL
;
1462 obj
->mtype
.subtype
= MEDIASUBTYPE_None
;
1463 obj
->mtype
.formattype
= FORMAT_None
;
1464 obj
->allocator
= NULL
;
1465 obj
->refClock
= NULL
;
1466 obj
->memOutput
= NULL
;
1467 obj
->grabberIface
= NULL
;
1468 obj
->grabberMethod
= -1;
1469 obj
->oneShot
= OneShot_None
;
1470 obj
->bufferLen
= -1;
1471 obj
->bufferData
= NULL
;