ReactOS 0.4.17-dev-966-gf06eace
smartteefilter.c File Reference
#include "qcap_private.h"
Include dependency graph for smartteefilter.c:

Go to the source code of this file.

Classes

struct  SmartTeeFilter
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (quartz)
 
static SmartTeeFilter * impl_from_strmbase_filter (struct strmbase_filter *filter)
 
static SmartTeeFilter * impl_from_strmbase_pin (struct strmbase_pin *pin)
 
static struct strmbase_pin * smart_tee_get_pin (struct strmbase_filter *iface, unsigned int index)
 
static void smart_tee_destroy (struct strmbase_filter *iface)
 
static HRESULT smart_tee_wait_state (struct strmbase_filter *iface, DWORD timeout)
 
static HRESULT sink_query_accept (struct strmbase_pin *base, const AM_MEDIA_TYPE *pmt)
 
static HRESULT sink_get_media_type (struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
 
static HRESULT sink_query_interface (struct strmbase_pin *iface, REFIID iid, void **out)
 
static HRESULT copy_sample (IMediaSample *inputSample, IMemAllocator *allocator, IMediaSample **pOutputSample)
 
static HRESULT WINAPI SmartTeeFilterInput_Receive (struct strmbase_sink *base, IMediaSample *inputSample)
 
static HRESULT capture_query_accept (struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
 
static HRESULT source_get_media_type (struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator (struct strmbase_source *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
 
static HRESULT preview_query_accept (struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
 
static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator (struct strmbase_source *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
 
HRESULT smart_tee_create (IUnknown *outer, IUnknown **out)
 

Variables

static const struct strmbase_filter_ops filter_ops
 
static const struct strmbase_sink_ops sink_ops
 
static const struct strmbase_source_ops capture_ops
 
static const struct strmbase_source_ops preview_ops
 

Function Documentation

◆ capture_query_accept()

static HRESULT capture_query_accept ( struct strmbase_pin *  base,
const AM_MEDIA_TYPE *  amt 
)
static

Definition at line 250 of file smartteefilter.c.

251{
252 FIXME("(%p) stub\n", base);
253 return S_OK;
254}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define S_OK
Definition: intsafe.h:52

◆ copy_sample()

static HRESULT copy_sample ( IMediaSample *  inputSample,
IMemAllocator *  allocator,
IMediaSample **  pOutputSample 
)
static

Definition at line 121 of file smartteefilter.c.

122{
123 REFERENCE_TIME startTime, endTime;
124 BOOL haveStartTime = TRUE, haveEndTime = TRUE;
125 IMediaSample *outputSample = NULL;
126 BYTE *ptrIn, *ptrOut;
127 AM_MEDIA_TYPE *mediaType = NULL;
128 HRESULT hr;
129
130 hr = IMediaSample_GetTime(inputSample, &startTime, &endTime);
131 if (hr == S_OK)
132 ;
133 else if (hr == VFW_S_NO_STOP_TIME)
134 haveEndTime = FALSE;
135 else if (hr == VFW_E_SAMPLE_TIME_NOT_SET)
136 haveStartTime = haveEndTime = FALSE;
137 else
138 goto end;
139
140 hr = IMemAllocator_GetBuffer(allocator, &outputSample,
141 haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL, 0);
142 if (FAILED(hr)) goto end;
143 if (IMediaSample_GetSize(outputSample) < IMediaSample_GetActualDataLength(inputSample)) {
144 ERR("insufficient space in sample\n");
146 goto end;
147 }
148
149 hr = IMediaSample_SetTime(outputSample, haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL);
150 if (FAILED(hr)) goto end;
151
152 hr = IMediaSample_GetPointer(inputSample, &ptrIn);
153 if (FAILED(hr)) goto end;
154 hr = IMediaSample_GetPointer(outputSample, &ptrOut);
155 if (FAILED(hr)) goto end;
156 memcpy(ptrOut, ptrIn, IMediaSample_GetActualDataLength(inputSample));
157 IMediaSample_SetActualDataLength(outputSample, IMediaSample_GetActualDataLength(inputSample));
158
159 hr = IMediaSample_SetDiscontinuity(outputSample, IMediaSample_IsDiscontinuity(inputSample) == S_OK);
160 if (FAILED(hr)) goto end;
161
162 haveStartTime = haveEndTime = TRUE;
163 hr = IMediaSample_GetMediaTime(inputSample, &startTime, &endTime);
164 if (hr == S_OK)
165 ;
166 else if (hr == VFW_S_NO_STOP_TIME)
167 haveEndTime = FALSE;
168 else if (hr == VFW_E_MEDIA_TIME_NOT_SET)
169 haveStartTime = haveEndTime = FALSE;
170 else
171 goto end;
172 hr = IMediaSample_SetMediaTime(outputSample, haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL);
173 if (FAILED(hr)) goto end;
174
175 hr = IMediaSample_GetMediaType(inputSample, &mediaType);
176 if (FAILED(hr)) goto end;
177 if (hr == S_OK) {
178 hr = IMediaSample_SetMediaType(outputSample, mediaType);
179 if (FAILED(hr)) goto end;
180 }
181
182 hr = IMediaSample_SetPreroll(outputSample, IMediaSample_IsPreroll(inputSample) == S_OK);
183 if (FAILED(hr)) goto end;
184
185 hr = IMediaSample_SetSyncPoint(outputSample, IMediaSample_IsSyncPoint(inputSample) == S_OK);
186 if (FAILED(hr)) goto end;
187
188end:
189 if (mediaType)
190 DeleteMediaType(mediaType);
191 if (FAILED(hr) && outputSample) {
192 IMediaSample_Release(outputSample);
193 outputSample = NULL;
194 }
195 *pOutputSample = outputSample;
196 return hr;
197}
#define ERR(fmt,...)
Definition: precomp.h:57
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static ULONGLONG startTime
Definition: main.c:113
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint end
Definition: gl.h:1545
#define FAILED(hr)
Definition: intsafe.h:51
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:193
#define VFW_E_SAMPLE_TIME_NOT_SET
Definition: vfwmsgs.h:104
#define VFW_E_MEDIA_TIME_NOT_SET
Definition: vfwmsgs.h:105
#define VFW_S_NO_STOP_TIME
Definition: vfwmsgs.h:34
#define VFW_E_BUFFER_OVERFLOW
Definition: vfwmsgs.h:52
unsigned char BYTE
Definition: xxhash.c:193

Referenced by SmartTeeFilterInput_Receive().

◆ impl_from_strmbase_filter()

static SmartTeeFilter * impl_from_strmbase_filter ( struct strmbase_filter *  filter)
inlinestatic

Definition at line 31 of file smartteefilter.c.

32{
34}
Definition: filter.c:165
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by impl_from_strmbase_pin(), smart_tee_destroy(), and smart_tee_get_pin().

◆ impl_from_strmbase_pin()

static SmartTeeFilter * impl_from_strmbase_pin ( struct strmbase_pin *  pin)
inlinestatic

Definition at line 36 of file smartteefilter.c.

37{
39}
static SmartTeeFilter * impl_from_strmbase_filter(struct strmbase_filter *filter)
struct strmbase_filter * filter
Definition: strmbase.h:58

Referenced by sink_get_media_type(), sink_query_accept(), sink_query_interface(), SmartTeeFilterCapture_DecideAllocator(), SmartTeeFilterInput_Receive(), SmartTeeFilterPreview_DecideAllocator(), and source_get_media_type().

◆ preview_query_accept()

static HRESULT preview_query_accept ( struct strmbase_pin *  base,
const AM_MEDIA_TYPE *  amt 
)
static

Definition at line 293 of file smartteefilter.c.

294{
295 FIXME("(%p) stub\n", base);
296 return S_OK;
297}

◆ sink_get_media_type()

static HRESULT sink_get_media_type ( struct strmbase_pin *  base,
unsigned int  iPosition,
AM_MEDIA_TYPE *  amt 
)
static

Definition at line 88 of file smartteefilter.c.

90{
92 HRESULT hr;
93 TRACE("(%p)->(%d, %p)\n", This, iPosition, amt);
94 if (iPosition)
95 return S_FALSE;
96 EnterCriticalSection(&This->filter.filter_cs);
97 if (This->sink.pin.peer)
98 {
99 CopyMediaType(amt, &This->sink.pin.mt);
100 hr = S_OK;
101 }
102 else
103 hr = S_FALSE;
104 LeaveCriticalSection(&This->filter.filter_cs);
105 return hr;
106}
static SmartTeeFilter * impl_from_strmbase_pin(struct strmbase_pin *pin)
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: mediatype.c:150
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define S_FALSE
Definition: winerror.h:3451

◆ sink_query_accept()

static HRESULT sink_query_accept ( struct strmbase_pin *  base,
const AM_MEDIA_TYPE *  pmt 
)
static

Definition at line 77 of file smartteefilter.c.

78{
80 TRACE("(%p, AM_MEDIA_TYPE(%p))\n", This, pmt);
81 if (!pmt)
83 /* We'll take any media type, but the output pins will later
84 * struggle to connect downstream. */
85 return S_OK;
86}
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81

◆ sink_query_interface()

static HRESULT sink_query_interface ( struct strmbase_pin *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 108 of file smartteefilter.c.

109{
111
112 if (IsEqualGUID(iid, &IID_IMemInputPin))
113 *out = &filter->sink.IMemInputPin_iface;
114 else
115 return E_NOINTERFACE;
116
117 IUnknown_AddRef((IUnknown *)*out);
118 return S_OK;
119}
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ smart_tee_create()

HRESULT smart_tee_create ( IUnknown *  outer,
IUnknown **  out 
)

Definition at line 317 of file smartteefilter.c.

318{
320 HRESULT hr;
321
322 if (!(object = calloc(1, sizeof(*object))))
323 return E_OUTOFMEMORY;
324
325 strmbase_filter_init(&object->filter, outer, &CLSID_SmartTee, &filter_ops);
326 strmbase_sink_init(&object->sink, &object->filter, L"Input", &sink_ops, NULL);
327 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
328 &IID_IMemAllocator, (void **)&object->sink.pAllocator);
329 if (FAILED(hr))
330 {
332 free(object);
333 return hr;
334 }
335
336 strmbase_source_init(&object->capture, &object->filter, L"Capture", &capture_ops);
337 strmbase_source_init(&object->preview, &object->filter, L"Preview", &preview_ops);
338
339 TRACE("Created smart tee %p.\n", object);
340 *out = &object->filter.IUnknown_inner;
341 return S_OK;
342}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#define L(x)
Definition: resources.c:13
static IUnknown * outer
Definition: compobj.c:82
#define calloc
Definition: rosglue.h:14
static const struct strmbase_source_ops preview_ops
static const struct strmbase_sink_ops sink_ops
static const struct strmbase_filter_ops filter_ops
static const struct strmbase_source_ops capture_ops
void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_source_ops *func_table)
Definition: pin.c:765
void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator)
Definition: pin.c:1168
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517

◆ smart_tee_destroy()

static void smart_tee_destroy ( struct strmbase_filter *  iface)
static

Definition at line 54 of file smartteefilter.c.

55{
57
62 free(filter);
63}
void strmbase_sink_cleanup(struct strmbase_sink *pin)
Definition: pin.c:1185
void strmbase_source_cleanup(struct strmbase_source *pin)
Definition: pin.c:778
IBaseFilter * filter
Definition: filtergraph.c:75

◆ smart_tee_get_pin()

static struct strmbase_pin * smart_tee_get_pin ( struct strmbase_filter *  iface,
unsigned int  index 
)
static

Definition at line 41 of file smartteefilter.c.

42{
44
45 if (index == 0)
46 return &filter->sink.pin;
47 else if (index == 1)
48 return &filter->capture.pin;
49 else if (index == 2)
50 return &filter->preview.pin;
51 return NULL;
52}
GLuint index
Definition: glext.h:6031

◆ smart_tee_wait_state()

static HRESULT smart_tee_wait_state ( struct strmbase_filter *  iface,
DWORD  timeout 
)
static

Definition at line 65 of file smartteefilter.c.

66{
67 return iface->state == State_Paused ? VFW_S_CANT_CUE : S_OK;
68}
FILTER_STATE state
Definition: strmbase.h:151
#define VFW_S_CANT_CUE
Definition: vfwmsgs.h:33

◆ SmartTeeFilterCapture_DecideAllocator()

static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator ( struct strmbase_source *  base,
IMemInputPin *  pPin,
IMemAllocator **  pAlloc 
)
static

Definition at line 275 of file smartteefilter.c.

277{
279 TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
280 *pAlloc = This->sink.pAllocator;
281 IMemAllocator_AddRef(This->sink.pAllocator);
282 return IMemInputPin_NotifyAllocator(pPin, This->sink.pAllocator, TRUE);
283}

◆ SmartTeeFilterInput_Receive()

static HRESULT WINAPI SmartTeeFilterInput_Receive ( struct strmbase_sink *  base,
IMediaSample *  inputSample 
)
static

Definition at line 199 of file smartteefilter.c.

200{
202 IMediaSample *captureSample = NULL;
203 IMediaSample *previewSample = NULL;
204 HRESULT hrCapture = VFW_E_NOT_CONNECTED, hrPreview = VFW_E_NOT_CONNECTED;
205
206 TRACE("(%p)->(%p)\n", This, inputSample);
207
208 /* Modifying the image coming out of one pin doesn't modify the image
209 * coming out of the other. MSDN claims the filter doesn't copy,
210 * but unless it somehow uses copy-on-write, I just don't see how
211 * that's possible. */
212
213 /* FIXME: we should ideally do each of these in a separate thread */
214 EnterCriticalSection(&This->filter.filter_cs);
215 if (This->capture.pin.peer)
216 hrCapture = copy_sample(inputSample, This->capture.pAllocator, &captureSample);
217 LeaveCriticalSection(&This->filter.filter_cs);
218 if (SUCCEEDED(hrCapture) && This->capture.pMemInputPin)
219 hrCapture = IMemInputPin_Receive(This->capture.pMemInputPin, captureSample);
220 if (captureSample)
221 IMediaSample_Release(captureSample);
222
223 EnterCriticalSection(&This->filter.filter_cs);
224 if (This->preview.pin.peer)
225 hrPreview = copy_sample(inputSample, This->preview.pAllocator, &previewSample);
226 LeaveCriticalSection(&This->filter.filter_cs);
227 /* No timestamps on preview stream: */
228 if (SUCCEEDED(hrPreview))
229 hrPreview = IMediaSample_SetTime(previewSample, NULL, NULL);
230 if (SUCCEEDED(hrPreview) && This->preview.pMemInputPin)
231 hrPreview = IMemInputPin_Receive(This->preview.pMemInputPin, previewSample);
232 if (previewSample)
233 IMediaSample_Release(previewSample);
234
235 /* FIXME: how to merge the HRESULTs from the 2 pins? */
236 if (SUCCEEDED(hrCapture))
237 return hrCapture;
238 else
239 return hrPreview;
240}
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static HRESULT copy_sample(IMediaSample *inputSample, IMemAllocator *allocator, IMediaSample **pOutputSample)
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48

◆ SmartTeeFilterPreview_DecideAllocator()

static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator ( struct strmbase_source *  base,
IMemInputPin *  pPin,
IMemAllocator **  pAlloc 
)
static

Definition at line 299 of file smartteefilter.c.

301{
303 TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
304 *pAlloc = This->sink.pAllocator;
305 IMemAllocator_AddRef(This->sink.pAllocator);
306 return IMemInputPin_NotifyAllocator(pPin, This->sink.pAllocator, TRUE);
307}

◆ source_get_media_type()

static HRESULT source_get_media_type ( struct strmbase_pin *  iface,
unsigned int  index,
AM_MEDIA_TYPE *  mt 
)
static

Definition at line 256 of file smartteefilter.c.

258{
260 HRESULT hr = S_OK;
261
263
264 if (!filter->sink.pin.peer)
266 else if (!index)
267 CopyMediaType(mt, &filter->sink.pin.mt);
268 else
270
272 return hr;
273}
#define VFW_S_NO_MORE_ITEMS
Definition: vfwmsgs.h:19

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( quartz  )

Variable Documentation

◆ capture_ops

const struct strmbase_source_ops capture_ops
static
Initial value:
=
{
.base.pin_query_accept = capture_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
}
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator(struct strmbase_source *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
static HRESULT capture_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: pin.c:710

Definition at line 285 of file smartteefilter.c.

Referenced by smart_tee_create().

◆ filter_ops

const struct strmbase_filter_ops filter_ops
static
Initial value:
=
{
.filter_get_pin = smart_tee_get_pin,
.filter_destroy = smart_tee_destroy,
.filter_wait_state = smart_tee_wait_state,
}
static void smart_tee_destroy(struct strmbase_filter *iface)
static struct strmbase_pin * smart_tee_get_pin(struct strmbase_filter *iface, unsigned int index)
static HRESULT smart_tee_wait_state(struct strmbase_filter *iface, DWORD timeout)

Definition at line 70 of file smartteefilter.c.

Referenced by smart_tee_create().

◆ preview_ops

const struct strmbase_source_ops preview_ops
static
Initial value:
=
{
.base.pin_query_accept = preview_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
}
static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator(struct strmbase_source *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
static HRESULT preview_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)

Definition at line 309 of file smartteefilter.c.

Referenced by smart_tee_create().

◆ sink_ops

const struct strmbase_sink_ops sink_ops
static
Initial value:
=
{
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = sink_get_media_type,
.base.pin_query_interface = sink_query_interface,
}
static HRESULT sink_get_media_type(struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
static HRESULT WINAPI SmartTeeFilterInput_Receive(struct strmbase_sink *base, IMediaSample *inputSample)
static HRESULT sink_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *pmt)
static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)

Definition at line 242 of file smartteefilter.c.

Referenced by smart_tee_create().