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 const WCHAR vendor_name
[] = { 'W', 'i', 'n', 'e', 0 };
36 static const WCHAR pin_in_name
[] = { 'I', 'n', 0 };
37 static const WCHAR 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
{
361 static inline SG_Pin
*impl_from_IPin(IPin
*iface
)
363 return CONTAINING_RECORD(iface
, SG_Pin
, IPin_iface
);
366 /* Sample Grabber filter implementation */
367 typedef struct _SG_Impl
{
368 IUnknown IUnknown_inner
;
369 IBaseFilter IBaseFilter_iface
;
370 ISampleGrabber ISampleGrabber_iface
;
371 IMemInputPin IMemInputPin_iface
;
372 /* IMediaSeeking and IMediaPosition are implemented by ISeekingPassThru */
373 IUnknown
* seekthru_unk
;
374 /* TODO: IQualityControl */
377 CRITICAL_SECTION critSect
;
383 IMemAllocator
*allocator
;
384 IReferenceClock
*refClock
;
385 IMemInputPin
*memOutput
;
386 ISampleGrabberCB
*grabberIface
;
399 static inline SG_Impl
*impl_from_IUnknown(IUnknown
*iface
)
401 return CONTAINING_RECORD(iface
, SG_Impl
, IUnknown_inner
);
404 static inline SG_Impl
*impl_from_IBaseFilter(IBaseFilter
*iface
)
406 return CONTAINING_RECORD(iface
, SG_Impl
, IBaseFilter_iface
);
409 static inline SG_Impl
*impl_from_ISampleGrabber(ISampleGrabber
*iface
)
411 return CONTAINING_RECORD(iface
, SG_Impl
, ISampleGrabber_iface
);
414 static inline SG_Impl
*impl_from_IMemInputPin(IMemInputPin
*iface
)
416 return CONTAINING_RECORD(iface
, SG_Impl
, IMemInputPin_iface
);
420 /* Cleanup at end of life */
421 static void SampleGrabber_cleanup(SG_Impl
*This
)
423 TRACE("(%p)\n", This
);
424 if (This
->info
.pGraph
)
425 WARN("(%p) still joined to filter graph %p\n", This
, This
->info
.pGraph
);
427 IMemAllocator_Release(This
->allocator
);
429 IReferenceClock_Release(This
->refClock
);
431 IMemInputPin_Release(This
->memOutput
);
432 if (This
->grabberIface
)
433 ISampleGrabberCB_Release(This
->grabberIface
);
434 if (This
->mtype
.pbFormat
)
435 CoTaskMemFree(This
->mtype
.pbFormat
);
436 if (This
->bufferData
)
437 CoTaskMemFree(This
->bufferData
);
438 if(This
->seekthru_unk
)
439 IUnknown_Release(This
->seekthru_unk
);
440 This
->critSect
.DebugInfo
->Spare
[0] = 0;
441 DeleteCriticalSection(&This
->critSect
);
444 /* SampleGrabber inner IUnknown */
445 static HRESULT WINAPI
SampleGrabber_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
447 SG_Impl
*This
= impl_from_IUnknown(iface
);
449 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
452 if (IsEqualIID(riid
, &IID_IUnknown
))
453 *ppv
= &This
->IUnknown_inner
;
454 else if (IsEqualIID(riid
, &IID_IPersist
) || IsEqualIID(riid
, &IID_IMediaFilter
) ||
455 IsEqualIID(riid
, &IID_IBaseFilter
))
456 *ppv
= &This
->IBaseFilter_iface
;
457 else if (IsEqualIID(riid
, &IID_ISampleGrabber
))
458 *ppv
= &This
->ISampleGrabber_iface
;
459 else if (IsEqualIID(riid
, &IID_IMemInputPin
))
460 *ppv
= &This
->IMemInputPin_iface
;
461 else if (IsEqualIID(riid
, &IID_IMediaPosition
))
462 return IUnknown_QueryInterface(This
->seekthru_unk
, riid
, ppv
);
463 else if (IsEqualIID(riid
, &IID_IMediaSeeking
))
464 return IUnknown_QueryInterface(This
->seekthru_unk
, riid
, ppv
);
465 else if (IsEqualIID(riid
, &IID_IQualityControl
))
466 FIXME("IQualityControl not implemented\n");
468 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppv
);
471 return E_NOINTERFACE
;
473 IUnknown_AddRef((IUnknown
*)*ppv
);
477 static ULONG WINAPI
SampleGrabber_AddRef(IUnknown
*iface
)
479 SG_Impl
*This
= impl_from_IUnknown(iface
);
480 ULONG ref
= InterlockedIncrement(&This
->ref
);
482 TRACE("(%p) new ref = %u\n", This
, ref
);
487 static ULONG WINAPI
SampleGrabber_Release(IUnknown
*iface
)
489 SG_Impl
*This
= impl_from_IUnknown(iface
);
490 ULONG ref
= InterlockedDecrement(&This
->ref
);
492 TRACE("(%p) new ref = %u\n", This
, ref
);
496 SampleGrabber_cleanup(This
);
503 static const IUnknownVtbl samplegrabber_vtbl
=
505 SampleGrabber_QueryInterface
,
506 SampleGrabber_AddRef
,
507 SampleGrabber_Release
,
510 /* Helper that buffers data and/or calls installed sample callbacks */
511 static void SampleGrabber_callback(SG_Impl
*This
, IMediaSample
*sample
)
514 REFERENCE_TIME tStart
, tEnd
;
515 if (This
->bufferLen
>= 0) {
517 LONG size
= IMediaSample_GetActualDataLength(sample
);
518 if (size
>= 0 && SUCCEEDED(IMediaSample_GetPointer(sample
, &data
))) {
521 EnterCriticalSection(&This
->critSect
);
522 if (This
->bufferLen
!= size
) {
523 if (This
->bufferData
)
524 CoTaskMemFree(This
->bufferData
);
525 This
->bufferData
= size
? CoTaskMemAlloc(size
) : NULL
;
526 This
->bufferLen
= size
;
529 CopyMemory(This
->bufferData
, data
, size
);
530 LeaveCriticalSection(&This
->critSect
);
533 if (!This
->grabberIface
)
535 if (SUCCEEDED(IMediaSample_GetTime(sample
, &tStart
, &tEnd
)))
536 time
= 1e-7 * tStart
;
537 switch (This
->grabberMethod
) {
540 ULONG ref
= IMediaSample_AddRef(sample
);
541 ISampleGrabberCB_SampleCB(This
->grabberIface
, time
, sample
);
542 ref
= IMediaSample_Release(sample
) + 1 - ref
;
545 ERR("(%p) Callback referenced sample %p by %u\n", This
, sample
, ref
);
546 /* ugly as hell but some apps are sooo buggy */
548 IMediaSample_Release(sample
);
555 LONG size
= IMediaSample_GetActualDataLength(sample
);
556 if (size
&& SUCCEEDED(IMediaSample_GetPointer(sample
, &data
)) && data
)
557 ISampleGrabberCB_BufferCB(This
->grabberIface
, time
, data
, size
);
563 FIXME("unsupported method %d\n", This
->grabberMethod
);
564 /* do not bother us again */
565 This
->grabberMethod
= -1;
570 /* SampleGrabber implementation of IBaseFilter interface */
573 static HRESULT WINAPI
574 SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter
*iface
, REFIID riid
, void **ppv
)
576 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
577 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
582 SampleGrabber_IBaseFilter_AddRef(IBaseFilter
*iface
)
584 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
585 return IUnknown_AddRef(This
->outer_unk
);
590 SampleGrabber_IBaseFilter_Release(IBaseFilter
*iface
)
592 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
593 return IUnknown_Release(This
->outer_unk
);
597 static HRESULT WINAPI
598 SampleGrabber_IBaseFilter_GetClassID(IBaseFilter
*iface
, CLSID
*pClassID
)
600 TRACE("(%p)\n", pClassID
);
603 *pClassID
= CLSID_SampleGrabber
;
608 static HRESULT WINAPI
609 SampleGrabber_IBaseFilter_Stop(IBaseFilter
*iface
)
611 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
612 TRACE("(%p)\n", This
);
613 This
->state
= State_Stopped
;
618 static HRESULT WINAPI
619 SampleGrabber_IBaseFilter_Pause(IBaseFilter
*iface
)
621 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
622 TRACE("(%p)\n", This
);
623 This
->state
= State_Paused
;
628 static HRESULT WINAPI
629 SampleGrabber_IBaseFilter_Run(IBaseFilter
*iface
, REFERENCE_TIME tStart
)
631 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
632 TRACE("(%p)\n", This
);
633 This
->state
= State_Running
;
638 static HRESULT WINAPI
639 SampleGrabber_IBaseFilter_GetState(IBaseFilter
*iface
, DWORD msTout
, FILTER_STATE
*state
)
641 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
642 TRACE("(%p)->(%u, %p)\n", This
, msTout
, state
);
645 *state
= This
->state
;
650 static HRESULT WINAPI
651 SampleGrabber_IBaseFilter_SetSyncSource(IBaseFilter
*iface
, IReferenceClock
*clock
)
653 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
654 TRACE("(%p)->(%p)\n", This
, clock
);
655 if (clock
!= This
->refClock
)
658 IReferenceClock_AddRef(clock
);
660 IReferenceClock_Release(This
->refClock
);
661 This
->refClock
= clock
;
667 static HRESULT WINAPI
668 SampleGrabber_IBaseFilter_GetSyncSource(IBaseFilter
*iface
, IReferenceClock
**clock
)
670 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
671 TRACE("(%p)->(%p)\n", This
, clock
);
675 IReferenceClock_AddRef(This
->refClock
);
676 *clock
= This
->refClock
;
681 static HRESULT WINAPI
682 SampleGrabber_IBaseFilter_EnumPins(IBaseFilter
*iface
, IEnumPins
**pins
)
684 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
686 TRACE("(%p)->(%p)\n", This
, pins
);
689 pin
[0] = &This
->pin_in
.IPin_iface
;
690 pin
[1] = &This
->pin_out
.IPin_iface
;
691 *pins
= pinsenum_create(iface
, pin
, 2);
692 return *pins
? S_OK
: E_OUTOFMEMORY
;
696 static HRESULT WINAPI
697 SampleGrabber_IBaseFilter_FindPin(IBaseFilter
*iface
, LPCWSTR id
, IPin
**pin
)
699 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
700 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(id
), pin
);
703 if (!lstrcmpiW(id
,pin_in_name
))
705 *pin
= &This
->pin_in
.IPin_iface
;
709 else if (!lstrcmpiW(id
,pin_out_name
))
711 *pin
= &This
->pin_out
.IPin_iface
;
716 return VFW_E_NOT_FOUND
;
720 static HRESULT WINAPI
721 SampleGrabber_IBaseFilter_QueryFilterInfo(IBaseFilter
*iface
, FILTER_INFO
*info
)
723 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
724 TRACE("(%p)->(%p)\n", This
, info
);
727 if (This
->info
.pGraph
)
728 IFilterGraph_AddRef(This
->info
.pGraph
);
734 static HRESULT WINAPI
735 SampleGrabber_IBaseFilter_JoinFilterGraph(IBaseFilter
*iface
, IFilterGraph
*graph
, LPCWSTR name
)
737 SG_Impl
*This
= impl_from_IBaseFilter(iface
);
738 TRACE("(%p)->(%p, %s)\n", This
, graph
, debugstr_w(name
));
739 This
->info
.pGraph
= graph
;
741 lstrcpynW(This
->info
.achName
,name
,MAX_FILTER_NAME
);
742 This
->oneShot
= OneShot_None
;
747 static HRESULT WINAPI
748 SampleGrabber_IBaseFilter_QueryVendorInfo(IBaseFilter
*iface
, LPWSTR
*vendor
)
750 TRACE("(%p)\n", vendor
);
753 *vendor
= CoTaskMemAlloc(sizeof(vendor_name
));
754 CopyMemory(*vendor
, vendor_name
, sizeof(vendor_name
));
759 /* SampleGrabber implementation of ISampleGrabber interface */
762 static HRESULT WINAPI
763 SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber
*iface
, REFIID riid
, void **ppv
)
765 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
766 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
771 SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber
*iface
)
773 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
774 return IUnknown_AddRef(This
->outer_unk
);
779 SampleGrabber_ISampleGrabber_Release(ISampleGrabber
*iface
)
781 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
782 return IUnknown_Release(This
->outer_unk
);
786 static HRESULT WINAPI
787 SampleGrabber_ISampleGrabber_SetOneShot(ISampleGrabber
*iface
, BOOL oneShot
)
789 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
790 TRACE("(%p)->(%u)\n", This
, oneShot
);
791 This
->oneShot
= oneShot
? OneShot_Wait
: OneShot_None
;
796 static HRESULT WINAPI
797 SampleGrabber_ISampleGrabber_SetMediaType(ISampleGrabber
*iface
, const AM_MEDIA_TYPE
*type
)
799 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
800 TRACE("(%p)->(%p)\n", This
, type
);
803 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
804 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
806 debugstr_guid(&type
->formattype
), type
->cbFormat
);
807 if (This
->mtype
.pbFormat
)
808 CoTaskMemFree(This
->mtype
.pbFormat
);
810 This
->mtype
.pUnk
= NULL
;
811 if (type
->cbFormat
) {
812 This
->mtype
.pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
813 CopyMemory(This
->mtype
.pbFormat
, type
->pbFormat
, type
->cbFormat
);
816 This
->mtype
.pbFormat
= NULL
;
821 static HRESULT WINAPI
822 SampleGrabber_ISampleGrabber_GetConnectedMediaType(ISampleGrabber
*iface
, AM_MEDIA_TYPE
*type
)
824 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
825 TRACE("(%p)->(%p)\n", This
, type
);
828 if (!This
->pin_in
.pair
)
829 return VFW_E_NOT_CONNECTED
;
831 if (type
->cbFormat
) {
832 type
->pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
833 CopyMemory(type
->pbFormat
, This
->mtype
.pbFormat
, type
->cbFormat
);
839 static HRESULT WINAPI
840 SampleGrabber_ISampleGrabber_SetBufferSamples(ISampleGrabber
*iface
, BOOL bufferEm
)
842 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
843 TRACE("(%p)->(%u)\n", This
, bufferEm
);
844 EnterCriticalSection(&This
->critSect
);
846 if (This
->bufferLen
< 0)
850 This
->bufferLen
= -1;
851 LeaveCriticalSection(&This
->critSect
);
856 static HRESULT WINAPI
857 SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber
*iface
, LONG
*bufSize
, LONG
*buffer
)
859 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
861 TRACE("(%p)->(%p, %p)\n", This
, bufSize
, buffer
);
864 EnterCriticalSection(&This
->critSect
);
865 if (!This
->pin_in
.pair
)
866 ret
= VFW_E_NOT_CONNECTED
;
867 else if (This
->bufferLen
< 0)
869 else if (This
->bufferLen
== 0)
870 ret
= VFW_E_WRONG_STATE
;
873 if (*bufSize
>= This
->bufferLen
)
874 CopyMemory(buffer
, This
->bufferData
, This
->bufferLen
);
878 *bufSize
= This
->bufferLen
;
880 LeaveCriticalSection(&This
->critSect
);
885 static HRESULT WINAPI
886 SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber
*iface
, IMediaSample
**sample
)
888 /* MS doesn't implement it either, no one should call it */
889 WARN("(%p): not implemented\n", sample
);
894 static HRESULT WINAPI
895 SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber
*iface
, ISampleGrabberCB
*cb
, LONG whichMethod
)
897 SG_Impl
*This
= impl_from_ISampleGrabber(iface
);
898 TRACE("(%p)->(%p, %u)\n", This
, cb
, whichMethod
);
899 if (This
->grabberIface
)
900 ISampleGrabberCB_Release(This
->grabberIface
);
901 This
->grabberIface
= cb
;
902 This
->grabberMethod
= whichMethod
;
904 ISampleGrabberCB_AddRef(cb
);
909 /* SampleGrabber implementation of IMemInputPin interface */
912 static HRESULT WINAPI
913 SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin
*iface
, REFIID riid
, void **ppv
)
915 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
916 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
921 SampleGrabber_IMemInputPin_AddRef(IMemInputPin
*iface
)
923 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
924 return IUnknown_AddRef(This
->outer_unk
);
929 SampleGrabber_IMemInputPin_Release(IMemInputPin
*iface
)
931 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
932 return IUnknown_Release(This
->outer_unk
);
936 static HRESULT WINAPI
937 SampleGrabber_IMemInputPin_GetAllocator(IMemInputPin
*iface
, IMemAllocator
**allocator
)
939 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
940 TRACE("(%p)->(%p) allocator = %p\n", This
, allocator
, This
->allocator
);
943 *allocator
= This
->allocator
;
945 return VFW_E_NO_ALLOCATOR
;
946 IMemAllocator_AddRef(*allocator
);
951 static HRESULT WINAPI
952 SampleGrabber_IMemInputPin_NotifyAllocator(IMemInputPin
*iface
, IMemAllocator
*allocator
, BOOL readOnly
)
954 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
955 TRACE("(%p)->(%p, %u) allocator = %p\n", This
, allocator
, readOnly
, This
->allocator
);
956 if (This
->allocator
== allocator
)
959 IMemAllocator_Release(This
->allocator
);
960 This
->allocator
= allocator
;
962 IMemAllocator_AddRef(allocator
);
967 static HRESULT WINAPI
968 SampleGrabber_IMemInputPin_GetAllocatorRequirements(IMemInputPin
*iface
, ALLOCATOR_PROPERTIES
*props
)
970 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
971 FIXME("(%p)->(%p): semi-stub\n", This
, props
);
974 return This
->memOutput
? IMemInputPin_GetAllocatorRequirements(This
->memOutput
, props
) : E_NOTIMPL
;
978 static HRESULT WINAPI
979 SampleGrabber_IMemInputPin_Receive(IMemInputPin
*iface
, IMediaSample
*sample
)
981 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
983 TRACE("(%p)->(%p) output = %p, grabber = %p\n", This
, sample
, This
->memOutput
, This
->grabberIface
);
986 if ((This
->state
!= State_Running
) || (This
->oneShot
== OneShot_Past
))
988 SampleGrabber_callback(This
, sample
);
989 hr
= This
->memOutput
? IMemInputPin_Receive(This
->memOutput
, sample
) : S_OK
;
990 if (This
->oneShot
== OneShot_Wait
) {
991 This
->oneShot
= OneShot_Past
;
993 if (This
->pin_out
.pair
)
994 IPin_EndOfStream(This
->pin_out
.pair
);
1000 static HRESULT WINAPI
1001 SampleGrabber_IMemInputPin_ReceiveMultiple(IMemInputPin
*iface
, IMediaSample
**samples
, LONG nSamples
, LONG
*nProcessed
)
1003 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
1005 TRACE("(%p)->(%p, %u, %p) output = %p, grabber = %p\n", This
, samples
, nSamples
, nProcessed
, This
->memOutput
, This
->grabberIface
);
1006 if (!samples
|| !nProcessed
)
1008 if ((This
->state
!= State_Running
) || (This
->oneShot
== OneShot_Past
))
1010 for (idx
= 0; idx
< nSamples
; idx
++)
1011 SampleGrabber_callback(This
, samples
[idx
]);
1012 return This
->memOutput
? IMemInputPin_ReceiveMultiple(This
->memOutput
, samples
, nSamples
, nProcessed
) : S_OK
;
1016 static HRESULT WINAPI
1017 SampleGrabber_IMemInputPin_ReceiveCanBlock(IMemInputPin
*iface
)
1019 SG_Impl
*This
= impl_from_IMemInputPin(iface
);
1020 TRACE("(%p)\n", This
);
1021 return This
->memOutput
? IMemInputPin_ReceiveCanBlock(This
->memOutput
) : S_OK
;
1025 /* SampleGrabber member pin implementation */
1029 SampleGrabber_IPin_AddRef(IPin
*iface
)
1031 SG_Pin
*This
= impl_from_IPin(iface
);
1032 return ISampleGrabber_AddRef(&This
->sg
->ISampleGrabber_iface
);
1037 SampleGrabber_IPin_Release(IPin
*iface
)
1039 SG_Pin
*This
= impl_from_IPin(iface
);
1040 return ISampleGrabber_Release(&This
->sg
->ISampleGrabber_iface
);
1044 static HRESULT WINAPI
1045 SampleGrabber_IPin_QueryInterface(IPin
*iface
, REFIID riid
, void **ppv
)
1047 SG_Pin
*This
= impl_from_IPin(iface
);
1048 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
1051 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IPin
))
1053 else if (IsEqualIID(riid
, &IID_IMemInputPin
))
1054 *ppv
= &This
->sg
->IMemInputPin_iface
;
1055 else if (IsEqualIID(riid
, &IID_IMediaSeeking
))
1056 return IUnknown_QueryInterface(&This
->sg
->IUnknown_inner
, riid
, ppv
);
1057 else if (IsEqualIID(riid
, &IID_IMediaPosition
))
1058 return IUnknown_QueryInterface(&This
->sg
->IUnknown_inner
, riid
, ppv
);
1060 WARN("(%p, %s,%p): not found\n", This
, debugstr_guid(riid
), ppv
);
1061 return E_NOINTERFACE
;
1064 IUnknown_AddRef((IUnknown
*)*ppv
);
1068 /* IPin - input pin */
1069 static HRESULT WINAPI
1070 SampleGrabber_In_IPin_Connect(IPin
*iface
, IPin
*receiver
, const AM_MEDIA_TYPE
*mtype
)
1072 WARN("(%p, %p): unexpected\n", receiver
, mtype
);
1073 return E_UNEXPECTED
;
1076 /* IPin - output pin */
1077 static HRESULT WINAPI
1078 SampleGrabber_Out_IPin_Connect(IPin
*iface
, IPin
*receiver
, const AM_MEDIA_TYPE
*type
)
1080 SG_Pin
*This
= impl_from_IPin(iface
);
1083 TRACE("(%p)->(%p, %p)\n", This
, receiver
, type
);
1087 return VFW_E_ALREADY_CONNECTED
;
1088 if (This
->sg
->state
!= State_Stopped
)
1089 return VFW_E_NOT_STOPPED
;
1091 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
1092 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
1094 debugstr_guid(&type
->formattype
), type
->cbFormat
);
1095 if (!IsEqualGUID(&This
->sg
->mtype
.majortype
,&GUID_NULL
) &&
1096 !IsEqualGUID(&This
->sg
->mtype
.majortype
,&type
->majortype
))
1097 return VFW_E_TYPE_NOT_ACCEPTED
;
1098 if (!IsEqualGUID(&This
->sg
->mtype
.subtype
,&MEDIASUBTYPE_None
) &&
1099 !IsEqualGUID(&This
->sg
->mtype
.subtype
,&type
->subtype
))
1100 return VFW_E_TYPE_NOT_ACCEPTED
;
1101 if (!IsEqualGUID(&This
->sg
->mtype
.formattype
,&GUID_NULL
) &&
1102 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&FORMAT_None
) &&
1103 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&type
->formattype
))
1104 return VFW_E_TYPE_NOT_ACCEPTED
;
1107 type
= &This
->sg
->mtype
;
1108 if (!IsEqualGUID(&type
->formattype
, &FORMAT_None
) &&
1109 !IsEqualGUID(&type
->formattype
, &GUID_NULL
) &&
1111 return VFW_E_TYPE_NOT_ACCEPTED
;
1112 hr
= IPin_ReceiveConnection(receiver
, &This
->IPin_iface
, type
);
1115 This
->pair
= receiver
;
1116 if (This
->sg
->memOutput
) {
1117 IMemInputPin_Release(This
->sg
->memOutput
);
1118 This
->sg
->memOutput
= NULL
;
1120 IPin_QueryInterface(receiver
,&IID_IMemInputPin
,(void **)&(This
->sg
->memOutput
));
1121 TRACE("(%p) Accepted IPin %p, IMemInputPin %p\n", This
, receiver
, This
->sg
->memOutput
);
1125 /* IPin - input pin */
1126 static HRESULT WINAPI
1127 SampleGrabber_In_IPin_ReceiveConnection(IPin
*iface
, IPin
*connector
, const AM_MEDIA_TYPE
*type
)
1129 SG_Pin
*This
= impl_from_IPin(iface
);
1131 TRACE("(%p)->(%p, %p)\n", This
, connector
, type
);
1135 return VFW_E_ALREADY_CONNECTED
;
1136 if (This
->sg
->state
!= State_Stopped
)
1137 return VFW_E_NOT_STOPPED
;
1139 TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
1140 debugstr_guid(&type
->majortype
), debugstr_guid(&type
->subtype
),
1142 debugstr_guid(&type
->formattype
), type
->cbFormat
);
1143 if (!IsEqualGUID(&type
->formattype
, &FORMAT_None
) &&
1144 !IsEqualGUID(&type
->formattype
, &GUID_NULL
) &&
1146 return VFW_E_INVALIDMEDIATYPE
;
1147 if (!IsEqualGUID(&This
->sg
->mtype
.majortype
,&GUID_NULL
) &&
1148 !IsEqualGUID(&This
->sg
->mtype
.majortype
,&type
->majortype
))
1149 return VFW_E_TYPE_NOT_ACCEPTED
;
1150 if (!IsEqualGUID(&This
->sg
->mtype
.subtype
,&MEDIASUBTYPE_None
) &&
1151 !IsEqualGUID(&This
->sg
->mtype
.subtype
,&type
->subtype
))
1152 return VFW_E_TYPE_NOT_ACCEPTED
;
1153 if (!IsEqualGUID(&This
->sg
->mtype
.formattype
,&GUID_NULL
) &&
1154 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&FORMAT_None
) &&
1155 !IsEqualGUID(&This
->sg
->mtype
.formattype
,&type
->formattype
))
1156 return VFW_E_TYPE_NOT_ACCEPTED
;
1157 if (This
->sg
->mtype
.pbFormat
)
1158 CoTaskMemFree(This
->sg
->mtype
.pbFormat
);
1159 This
->sg
->mtype
= *type
;
1160 This
->sg
->mtype
.pUnk
= NULL
;
1161 if (type
->cbFormat
) {
1162 This
->sg
->mtype
.pbFormat
= CoTaskMemAlloc(type
->cbFormat
);
1163 CopyMemory(This
->sg
->mtype
.pbFormat
, type
->pbFormat
, type
->cbFormat
);
1166 This
->sg
->mtype
.pbFormat
= NULL
;
1168 This
->pair
= connector
;
1169 TRACE("(%p) Accepted IPin %p\n", This
, connector
);
1173 /* IPin - output pin */
1174 static HRESULT WINAPI
1175 SampleGrabber_Out_IPin_ReceiveConnection(IPin
*iface
, IPin
*connector
, const AM_MEDIA_TYPE
*mtype
)
1177 WARN("(%p, %p): unexpected\n", connector
, mtype
);
1178 return E_UNEXPECTED
;
1181 /* IPin - input pin */
1182 static HRESULT WINAPI
1183 SampleGrabber_In_IPin_Disconnect(IPin
*iface
)
1185 SG_Pin
*This
= impl_from_IPin(iface
);
1187 TRACE("(%p)->() pair = %p\n", This
, This
->pair
);
1188 if (This
->sg
->state
!= State_Stopped
)
1189 return VFW_E_NOT_STOPPED
;
1197 /* IPin - output pin */
1198 static HRESULT WINAPI
1199 SampleGrabber_Out_IPin_Disconnect(IPin
*iface
)
1201 SG_Pin
*This
= impl_from_IPin(iface
);
1203 TRACE("(%p)->() pair = %p\n", This
, This
->pair
);
1204 if (This
->sg
->state
!= State_Stopped
)
1205 return VFW_E_NOT_STOPPED
;
1208 if (This
->sg
->memOutput
) {
1209 IMemInputPin_Release(This
->sg
->memOutput
);
1210 This
->sg
->memOutput
= NULL
;
1218 static HRESULT WINAPI
1219 SampleGrabber_IPin_ConnectedTo(IPin
*iface
, IPin
**pin
)
1221 SG_Pin
*This
= impl_from_IPin(iface
);
1223 TRACE("(%p)->(%p) pair = %p\n", This
, pin
, This
->pair
);
1231 return VFW_E_NOT_CONNECTED
;
1235 static HRESULT WINAPI
1236 SampleGrabber_IPin_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mtype
)
1238 SG_Pin
*This
= impl_from_IPin(iface
);
1240 TRACE("(%p)->(%p)\n", This
, mtype
);
1244 return VFW_E_NOT_CONNECTED
;
1245 *mtype
= This
->sg
->mtype
;
1246 if (mtype
->cbFormat
) {
1247 mtype
->pbFormat
= CoTaskMemAlloc(mtype
->cbFormat
);
1248 CopyMemory(mtype
->pbFormat
, This
->sg
->mtype
.pbFormat
, mtype
->cbFormat
);
1254 static HRESULT WINAPI
1255 SampleGrabber_IPin_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
1257 SG_Pin
*This
= impl_from_IPin(iface
);
1259 TRACE("(%p)->(%p)\n", This
, info
);
1262 IBaseFilter_AddRef(&This
->sg
->IBaseFilter_iface
);
1263 info
->pFilter
= &This
->sg
->IBaseFilter_iface
;
1264 info
->dir
= This
->dir
;
1265 lstrcpynW(info
->achName
,This
->name
,MAX_PIN_NAME
);
1270 static HRESULT WINAPI
1271 SampleGrabber_IPin_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
1273 SG_Pin
*This
= impl_from_IPin(iface
);
1275 TRACE("(%p)->(%p)\n", This
, dir
);
1283 static HRESULT WINAPI
1284 SampleGrabber_IPin_QueryId(IPin
*iface
, LPWSTR
*id
)
1286 SG_Pin
*This
= impl_from_IPin(iface
);
1289 TRACE("(%p)->(%p)\n", This
, id
);
1292 len
= sizeof(WCHAR
)*(1+lstrlenW(This
->name
));
1293 *id
= CoTaskMemAlloc(len
);
1294 CopyMemory(*id
, This
->name
, len
);
1299 static HRESULT WINAPI
1300 SampleGrabber_IPin_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mtype
)
1302 TRACE("(%p)\n", mtype
);
1307 static HRESULT WINAPI
1308 SampleGrabber_IPin_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**mtypes
)
1310 SG_Pin
*This
= impl_from_IPin(iface
);
1312 TRACE("(%p)->(%p)\n", This
, mtypes
);
1315 *mtypes
= mediaenum_create(This
->sg
->pin_in
.pair
? &This
->sg
->mtype
: NULL
);
1316 return *mtypes
? S_OK
: E_OUTOFMEMORY
;
1319 /* IPin - input pin */
1320 static HRESULT WINAPI
1321 SampleGrabber_In_IPin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*nPins
)
1323 SG_Pin
*This
= impl_from_IPin(iface
);
1325 TRACE("(%p)->(%p, %p) size = %u\n", This
, pins
, nPins
, (nPins
? *nPins
: 0));
1331 IPin_AddRef(&This
->sg
->pin_out
.IPin_iface
);
1332 *pins
= &This
->sg
->pin_out
.IPin_iface
;
1340 /* IPin - output pin */
1341 static HRESULT WINAPI
1342 SampleGrabber_Out_IPin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*nPins
)
1344 WARN("(%p, %p): unexpected\n", pins
, nPins
);
1351 static HRESULT WINAPI
1352 SampleGrabber_IPin_EndOfStream(IPin
*iface
)
1359 static HRESULT WINAPI
1360 SampleGrabber_IPin_BeginFlush(IPin
*iface
)
1367 static HRESULT WINAPI
1368 SampleGrabber_IPin_EndFlush(IPin
*iface
)
1375 static HRESULT WINAPI
1376 SampleGrabber_IPin_NewSegment(IPin
*iface
, REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double rate
)
1383 /* SampleGrabber vtables and constructor */
1385 static const IBaseFilterVtbl IBaseFilter_VTable
=
1387 SampleGrabber_IBaseFilter_QueryInterface
,
1388 SampleGrabber_IBaseFilter_AddRef
,
1389 SampleGrabber_IBaseFilter_Release
,
1390 SampleGrabber_IBaseFilter_GetClassID
,
1391 SampleGrabber_IBaseFilter_Stop
,
1392 SampleGrabber_IBaseFilter_Pause
,
1393 SampleGrabber_IBaseFilter_Run
,
1394 SampleGrabber_IBaseFilter_GetState
,
1395 SampleGrabber_IBaseFilter_SetSyncSource
,
1396 SampleGrabber_IBaseFilter_GetSyncSource
,
1397 SampleGrabber_IBaseFilter_EnumPins
,
1398 SampleGrabber_IBaseFilter_FindPin
,
1399 SampleGrabber_IBaseFilter_QueryFilterInfo
,
1400 SampleGrabber_IBaseFilter_JoinFilterGraph
,
1401 SampleGrabber_IBaseFilter_QueryVendorInfo
,
1404 static const ISampleGrabberVtbl ISampleGrabber_VTable
=
1406 SampleGrabber_ISampleGrabber_QueryInterface
,
1407 SampleGrabber_ISampleGrabber_AddRef
,
1408 SampleGrabber_ISampleGrabber_Release
,
1409 SampleGrabber_ISampleGrabber_SetOneShot
,
1410 SampleGrabber_ISampleGrabber_SetMediaType
,
1411 SampleGrabber_ISampleGrabber_GetConnectedMediaType
,
1412 SampleGrabber_ISampleGrabber_SetBufferSamples
,
1413 SampleGrabber_ISampleGrabber_GetCurrentBuffer
,
1414 SampleGrabber_ISampleGrabber_GetCurrentSample
,
1415 SampleGrabber_ISampleGrabber_SetCallback
,
1418 static const IMemInputPinVtbl IMemInputPin_VTable
=
1420 SampleGrabber_IMemInputPin_QueryInterface
,
1421 SampleGrabber_IMemInputPin_AddRef
,
1422 SampleGrabber_IMemInputPin_Release
,
1423 SampleGrabber_IMemInputPin_GetAllocator
,
1424 SampleGrabber_IMemInputPin_NotifyAllocator
,
1425 SampleGrabber_IMemInputPin_GetAllocatorRequirements
,
1426 SampleGrabber_IMemInputPin_Receive
,
1427 SampleGrabber_IMemInputPin_ReceiveMultiple
,
1428 SampleGrabber_IMemInputPin_ReceiveCanBlock
,
1431 static const IPinVtbl IPin_In_VTable
=
1433 SampleGrabber_IPin_QueryInterface
,
1434 SampleGrabber_IPin_AddRef
,
1435 SampleGrabber_IPin_Release
,
1436 SampleGrabber_In_IPin_Connect
,
1437 SampleGrabber_In_IPin_ReceiveConnection
,
1438 SampleGrabber_In_IPin_Disconnect
,
1439 SampleGrabber_IPin_ConnectedTo
,
1440 SampleGrabber_IPin_ConnectionMediaType
,
1441 SampleGrabber_IPin_QueryPinInfo
,
1442 SampleGrabber_IPin_QueryDirection
,
1443 SampleGrabber_IPin_QueryId
,
1444 SampleGrabber_IPin_QueryAccept
,
1445 SampleGrabber_IPin_EnumMediaTypes
,
1446 SampleGrabber_In_IPin_QueryInternalConnections
,
1447 SampleGrabber_IPin_EndOfStream
,
1448 SampleGrabber_IPin_BeginFlush
,
1449 SampleGrabber_IPin_EndFlush
,
1450 SampleGrabber_IPin_NewSegment
,
1453 static const IPinVtbl IPin_Out_VTable
=
1455 SampleGrabber_IPin_QueryInterface
,
1456 SampleGrabber_IPin_AddRef
,
1457 SampleGrabber_IPin_Release
,
1458 SampleGrabber_Out_IPin_Connect
,
1459 SampleGrabber_Out_IPin_ReceiveConnection
,
1460 SampleGrabber_Out_IPin_Disconnect
,
1461 SampleGrabber_IPin_ConnectedTo
,
1462 SampleGrabber_IPin_ConnectionMediaType
,
1463 SampleGrabber_IPin_QueryPinInfo
,
1464 SampleGrabber_IPin_QueryDirection
,
1465 SampleGrabber_IPin_QueryId
,
1466 SampleGrabber_IPin_QueryAccept
,
1467 SampleGrabber_IPin_EnumMediaTypes
,
1468 SampleGrabber_Out_IPin_QueryInternalConnections
,
1469 SampleGrabber_IPin_EndOfStream
,
1470 SampleGrabber_IPin_BeginFlush
,
1471 SampleGrabber_IPin_EndFlush
,
1472 SampleGrabber_IPin_NewSegment
,
1475 HRESULT
SampleGrabber_create(IUnknown
*pUnkOuter
, LPVOID
*ppv
)
1477 SG_Impl
* obj
= NULL
;
1478 ISeekingPassThru
*passthru
;
1481 TRACE("(%p,%p)\n", ppv
, pUnkOuter
);
1483 obj
= CoTaskMemAlloc(sizeof(SG_Impl
));
1486 return E_OUTOFMEMORY
;
1488 ZeroMemory(obj
, sizeof(SG_Impl
));
1491 obj
->IUnknown_inner
.lpVtbl
= &samplegrabber_vtbl
;
1492 obj
->IBaseFilter_iface
.lpVtbl
= &IBaseFilter_VTable
;
1493 obj
->ISampleGrabber_iface
.lpVtbl
= &ISampleGrabber_VTable
;
1494 obj
->IMemInputPin_iface
.lpVtbl
= &IMemInputPin_VTable
;
1495 obj
->pin_in
.IPin_iface
.lpVtbl
= &IPin_In_VTable
;
1496 obj
->pin_in
.dir
= PINDIR_INPUT
;
1497 obj
->pin_in
.name
= pin_in_name
;
1498 obj
->pin_in
.sg
= obj
;
1499 obj
->pin_in
.pair
= NULL
;
1500 obj
->pin_out
.IPin_iface
.lpVtbl
= &IPin_Out_VTable
;
1501 obj
->pin_out
.dir
= PINDIR_OUTPUT
;
1502 obj
->pin_out
.name
= pin_out_name
;
1503 obj
->pin_out
.sg
= obj
;
1504 obj
->pin_out
.pair
= NULL
;
1505 InitializeCriticalSection(&obj
->critSect
);
1506 obj
->critSect
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": SG_Impl.critSect");
1507 obj
->info
.achName
[0] = 0;
1508 obj
->info
.pGraph
= NULL
;
1509 obj
->state
= State_Stopped
;
1510 obj
->mtype
.majortype
= GUID_NULL
;
1511 obj
->mtype
.subtype
= MEDIASUBTYPE_None
;
1512 obj
->mtype
.formattype
= FORMAT_None
;
1513 obj
->allocator
= NULL
;
1514 obj
->refClock
= NULL
;
1515 obj
->memOutput
= NULL
;
1516 obj
->grabberIface
= NULL
;
1517 obj
->grabberMethod
= -1;
1518 obj
->oneShot
= OneShot_None
;
1519 obj
->bufferLen
= -1;
1520 obj
->bufferData
= NULL
;
1523 obj
->outer_unk
= pUnkOuter
;
1525 obj
->outer_unk
= &obj
->IUnknown_inner
;
1527 hr
= CoCreateInstance(&CLSID_SeekingPassThru
, (IUnknown
*)obj
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void**)&obj
->seekthru_unk
);
1530 IUnknown_QueryInterface(obj
->seekthru_unk
, &IID_ISeekingPassThru
, (void**)&passthru
);
1531 ISeekingPassThru_Init(passthru
, FALSE
, &obj
->pin_in
.IPin_iface
);
1532 ISeekingPassThru_Release(passthru
);
1534 *ppv
= &obj
->IUnknown_inner
;