Mercurial > mplayer.hg
annotate loader/dshow/inputpin.c @ 22298:a34c7ed7ff6d
Move EDL code to separate functions
author | uau |
---|---|
date | Thu, 22 Feb 2007 21:05:31 +0000 |
parents | 24dc4ec0d08d |
children | 3d1b23cf3d08 |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9964
diff
changeset
|
1 /* |
18783 | 2 * Modified for use with MPlayer, detailed changelog at |
3 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9964
diff
changeset
|
4 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9964
diff
changeset
|
5 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9964
diff
changeset
|
6 |
168 | 7 #include "inputpin.h" |
2069 | 8 #include "wine/winerror.h" |
1545 | 9 #include <string.h> |
168 | 10 #include <stdio.h> |
11 #include <stdlib.h> | |
1545 | 12 |
7386 | 13 static inline int unimplemented(const char* s, void* p) |
1545 | 14 { |
3056 | 15 Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); |
16 return E_NOTIMPL; | |
17 } | |
1545 | 18 |
3056 | 19 /*********** |
20 * EnumPins | |
21 ***********/ | |
168 | 22 |
3056 | 23 typedef struct |
168 | 24 { |
3056 | 25 IEnumPins_vt* vt; |
3467 | 26 DECLARE_IUNKNOWN(); |
168 | 27 IPin* pin1; |
28 IPin* pin2; | |
29 int counter; | |
3056 | 30 GUID interfaces[2]; |
31 } CEnumPins; | |
1545 | 32 |
22028 | 33 /** |
34 * \brief IEnumPins:Next (retrives a specified number of pins ) | |
35 * | |
36 * \param[in] This pointer to CEnumPins object | |
37 * \param[in] cMediaTypes number of pins to retrive | |
38 * \param[out] ppMediaTypes array of IPin interface pointers of size cMediaTypes | |
39 * \param[out] pcFetched address of variables that receives number of returned pins | |
40 * | |
41 * \return S_OK - success | |
42 * \return S_FALSE - did not return as meny pins as requested | |
43 * \return E_INVALIDARG Invalid argument | |
44 * \return E_POINTER Null pointer | |
45 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator | |
46 * | |
47 */ | |
3056 | 48 static long STDCALL CEnumPins_Next(IEnumPins* This, |
49 /* [in] */ unsigned long cMediaTypes, | |
3130 | 50 /* [size_is][out] */ IPin** ppMediaTypes, |
51 /* [out] */ unsigned long* pcFetched) | |
168 | 52 { |
3056 | 53 CEnumPins* pin = (CEnumPins*)This; |
168 | 54 |
3056 | 55 Debug printf("CEnumPins_Next(%p) called\n", This); |
1545 | 56 if (!ppMediaTypes) |
57 return E_INVALIDARG; | |
58 if (!pcFetched && (cMediaTypes!=1)) | |
59 return E_INVALIDARG; | |
60 if (cMediaTypes<=0) | |
61 return 0; | |
62 | |
3056 | 63 //lcounter = ((CEnumPins*)This)->counter; |
64 //lpin1 = ((CEnumPins*)This)->pin1; | |
65 //lpin2 = ((CEnumPins*)This)->pin2; | |
66 if (((pin->counter == 2) && pin->pin2) | |
67 || ((pin->counter == 1) && !pin->pin2)) | |
168 | 68 { |
1545 | 69 if (pcFetched) |
70 *pcFetched=0; | |
168 | 71 return 1; |
72 } | |
1545 | 73 |
74 if (pcFetched) | |
75 *pcFetched=1; | |
3056 | 76 if (pin->counter==0) |
168 | 77 { |
3056 | 78 *ppMediaTypes = pin->pin1; |
79 pin->pin1->vt->AddRef((IUnknown*)pin->pin1); | |
168 | 80 } |
81 else | |
82 { | |
3056 | 83 *ppMediaTypes = pin->pin2; |
84 pin->pin2->vt->AddRef((IUnknown*)pin->pin2); | |
168 | 85 } |
3056 | 86 pin->counter++; |
1545 | 87 if (cMediaTypes == 1) |
88 return 0; | |
168 | 89 return 1; |
90 } | |
91 | |
22028 | 92 /** |
93 * \brief IEnumPins::Skip (skips over a specified number of pins) | |
94 * | |
95 * \param[in] This pointer to CEnumPinss object | |
96 * \param[in] cMediaTypes number of pins to skip | |
97 * | |
98 * \return S_OK - success | |
99 * \return S_FALSE - skipped past the end of the sequence | |
100 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator | |
101 * | |
102 */ | |
3056 | 103 static long STDCALL CEnumPins_Skip(IEnumPins* This, |
104 /* [in] */ unsigned long cMediaTypes) | |
168 | 105 { |
3056 | 106 Debug unimplemented("CEnumPins_Skip", This); |
168 | 107 return E_NOTIMPL; |
108 } | |
109 | |
22028 | 110 /** |
111 * \brief IEnumPins::Reset (resets enumeration sequence to beginning) | |
112 * | |
113 * \param[in] This pointer to CEnumPins object | |
114 * | |
115 * \return S_OK - success | |
116 * | |
117 */ | |
3056 | 118 static long STDCALL CEnumPins_Reset(IEnumPins* This) |
168 | 119 { |
3056 | 120 Debug printf("CEnumPins_Reset(%p) called\n", This); |
121 ((CEnumPins*)This)->counter = 0; | |
168 | 122 return 0; |
123 } | |
124 | |
22028 | 125 /** |
126 * \brief IEnumPins::Clone (makes a copy of enumerator, returned object | |
127 * starts at the same position as original) | |
128 * | |
129 * \param[in] This pointer to CEnumPins object | |
130 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface | |
131 * | |
132 * \return S_OK - success | |
133 * \return E_OUTOFMEMRY - Insufficient memory | |
134 * \return E_POINTER - Null pointer | |
135 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator | |
136 * | |
137 */ | |
3056 | 138 static long STDCALL CEnumPins_Clone(IEnumPins* This, |
139 /* [out] */ IEnumPins** ppEnum) | |
168 | 140 { |
3056 | 141 Debug unimplemented("CEnumPins_Clone", This); |
168 | 142 return E_NOTIMPL; |
143 } | |
1545 | 144 |
22028 | 145 /** |
146 * \brief CEnumPins destructor | |
147 * | |
148 * \param[in] This pointer to CEnumPins object | |
149 * | |
150 */ | |
3056 | 151 static void CEnumPins_Destroy(CEnumPins* This) |
168 | 152 { |
3056 | 153 free(This->vt); |
154 free(This); | |
168 | 155 } |
156 | |
3056 | 157 IMPLEMENT_IUNKNOWN(CEnumPins) |
158 | |
22028 | 159 /** |
160 * \brief CEnumPins constructor | |
161 * | |
162 * \param[in] p first pin for enumerator | |
163 * \param[in] pp second pin for enumerator | |
164 * | |
165 * \return pointer to CEnumPins object or NULL if error occured | |
166 * | |
167 */ | |
3056 | 168 static CEnumPins* CEnumPinsCreate(IPin* p, IPin* pp) |
168 | 169 { |
3056 | 170 CEnumPins* This = (CEnumPins*) malloc(sizeof(CEnumPins)); |
171 | |
3467 | 172 if (!This) |
173 return NULL; | |
174 | |
175 This->refcount = 1; | |
3056 | 176 This->pin1 = p; |
177 This->pin2 = pp; | |
178 This->counter = 0; | |
179 | |
180 This->vt = (IEnumPins_vt*) malloc(sizeof(IEnumPins_vt)); | |
3467 | 181 if (!This->vt) |
182 { | |
183 free(This); | |
184 return NULL; | |
185 } | |
3056 | 186 This->vt->QueryInterface = CEnumPins_QueryInterface; |
187 This->vt->AddRef = CEnumPins_AddRef; | |
188 This->vt->Release = CEnumPins_Release; | |
189 This->vt->Next = CEnumPins_Next; | |
190 This->vt->Skip = CEnumPins_Skip; | |
191 This->vt->Reset = CEnumPins_Reset; | |
192 This->vt->Clone = CEnumPins_Clone; | |
193 | |
194 This->interfaces[0] = IID_IUnknown; | |
195 This->interfaces[1] = IID_IEnumPins; | |
196 | |
197 return This; | |
198 } | |
199 | |
200 | |
201 | |
202 /*********** | |
203 * InputPin | |
22028 | 204 * |
205 * WARNING: | |
206 * This is implementation of OUTPUT pin in DirectShow's terms | |
207 * | |
3056 | 208 ***********/ |
209 | |
22028 | 210 /** |
211 * \brief IPin::Connect (connects pin to another pin) | |
212 * | |
213 * \param[in] This pointer to IPin interface | |
214 * \param[in] pReceivePin pointer to IPin interface of remote pin | |
215 * \param[in] pmt suggested media type for link. Can be NULL (any media type) | |
216 * | |
217 * \return S_OK - success. | |
218 * \return VFW_E_ALREADY_CONNECTED - pin already connected | |
219 * \return VFW_E_NOT_STOPPED - filter is active | |
220 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable | |
221 * \return Apropriate error code otherwise. | |
222 * | |
223 */ | |
3130 | 224 static long STDCALL CInputPin_Connect(IPin* This, |
225 /* [in] */ IPin* pReceivePin, | |
226 /* [in] */ AM_MEDIA_TYPE* pmt) | |
3056 | 227 { |
228 Debug unimplemented("CInputPin_Connect", This); | |
168 | 229 return E_NOTIMPL; |
230 } | |
231 | |
22028 | 232 /** |
233 * \brief IPin::ReceiveConnection (accepts a connection from another pin) | |
234 * | |
235 * \param[in] This pointer to IPin interface | |
236 * \param[in] pConnector connecting pin's IPin interface | |
237 * \param[in] pmt suggested media type for connection | |
238 * | |
239 * \return S_OK - success | |
240 * \return E_POINTER - Null pointer | |
241 * \return VFW_E_ALREADY_CONNECTED - pin already connected | |
242 * \return VFW_E_NOT_STOPPED - filter is active | |
243 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable | |
244 * | |
245 * \note | |
246 * When returning S_OK method should also do the following: | |
247 * - store media type and return the same type in IPin::ConnectionMediaType | |
248 * - store pConnector and return it in IPin::ConnectedTo | |
249 * | |
250 */ | |
3056 | 251 static long STDCALL CInputPin_ReceiveConnection(IPin* This, |
252 /* [in] */ IPin* pConnector, | |
253 /* [in] */ const AM_MEDIA_TYPE *pmt) | |
168 | 254 { |
3056 | 255 Debug unimplemented("CInputPin_ReceiveConnection", This); |
168 | 256 return E_NOTIMPL; |
257 } | |
1545 | 258 |
22028 | 259 /** |
260 * \brief IPin::Disconnect (accepts a connection from another pin) | |
261 * | |
262 * \param[in] This pointer to IPin interface | |
263 * | |
264 * \return S_OK - success | |
265 * \return S_FALSE - pin was not connected | |
266 * \return VFW_E_NOT_STOPPED - filter is active | |
267 * | |
268 * \note | |
269 * To break connection you have to also call Disconnect on other pin | |
270 */ | |
3056 | 271 static long STDCALL CInputPin_Disconnect(IPin* This) |
168 | 272 { |
3056 | 273 Debug unimplemented("CInputPin_Disconnect", This); |
168 | 274 return E_NOTIMPL; |
275 } | |
276 | |
22028 | 277 /** |
278 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist) | |
279 * | |
280 * \param[in] This pointer to IPin interface | |
281 * \param[out] pPin pointer to remote pin's IPin interface | |
282 * | |
283 * \return S_OK - success | |
284 * \return E_POINTER - Null pointer | |
285 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
286 * | |
287 * \note | |
288 * Caller must call Release on received IPin, when done | |
289 */ | |
3056 | 290 static long STDCALL CInputPin_ConnectedTo(IPin* This, |
291 /* [out] */ IPin** pPin) | |
168 | 292 { |
3056 | 293 Debug unimplemented("CInputPin_ConnectedTo", This); |
168 | 294 return E_NOTIMPL; |
295 } | |
296 | |
22028 | 297 /** |
298 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist) | |
299 * | |
300 * \param[in] This pointer to IPin interface | |
301 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type | |
302 * | |
303 * \return S_OK - success | |
304 * \return E_POINTER - Null pointer | |
305 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
306 * | |
307 */ | |
3056 | 308 static long STDCALL CInputPin_ConnectionMediaType(IPin* This, |
309 /* [out] */ AM_MEDIA_TYPE *pmt) | |
168 | 310 { |
3056 | 311 Debug printf("CInputPin_ConnectionMediaType(%p) called\n", This); |
312 if (!pmt) | |
313 return E_INVALIDARG; | |
168 | 314 *pmt=((CInputPin*)This)->type; |
3056 | 315 if (pmt->cbFormat > 0) |
168 | 316 { |
18878 | 317 pmt->pbFormat=malloc(pmt->cbFormat); |
168 | 318 memcpy(pmt->pbFormat, ((CInputPin*)This)->type.pbFormat, pmt->cbFormat); |
1545 | 319 } |
168 | 320 return 0; |
321 } | |
322 | |
22028 | 323 /** |
324 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
325 * | |
326 * \param[in] This pointer to IPin interface | |
327 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
328 * | |
329 * \return S_OK - success | |
330 * \return E_POINTER - Null pointer | |
331 * | |
332 * \note | |
333 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
334 * | |
335 */ | |
3056 | 336 static long STDCALL CInputPin_QueryPinInfo(IPin* This, |
337 /* [out] */ PIN_INFO *pInfo) | |
168 | 338 { |
1545 | 339 CBaseFilter* lparent=((CInputPin*)This)->parent; |
3056 | 340 Debug printf("CInputPin_QueryPinInfo(%p) called\n", This); |
341 pInfo->dir = PINDIR_OUTPUT; | |
342 pInfo->pFilter = (IBaseFilter*) lparent; | |
1545 | 343 lparent->vt->AddRef((IUnknown*)lparent); |
3056 | 344 pInfo->achName[0] = 0; |
345 return 0; | |
346 } | |
347 | |
22028 | 348 /** |
349 * \brief IPin::QueryDirection (retrieves pin direction) | |
350 * | |
351 * \param[in] This pointer to IPin interface | |
352 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) | |
353 * | |
354 * \return S_OK - success | |
355 * \return E_POINTER - Null pointer | |
356 * | |
357 */ | |
3056 | 358 static long STDCALL CInputPin_QueryDirection(IPin* This, |
359 /* [out] */ PIN_DIRECTION *pPinDir) | |
360 { | |
361 *pPinDir = PINDIR_OUTPUT; | |
362 Debug printf("CInputPin_QueryDirection(%p) called\n", This); | |
168 | 363 return 0; |
364 } | |
365 | |
22028 | 366 /** |
367 * \brief IPin::QueryId (retrieves pin identificator) | |
368 * | |
369 * \param[in] This pointer to IPin interface | |
370 * \param[out] Id adress of variable, that receives string with pin's Id. | |
371 * | |
372 * \return S_OK - success | |
373 * \return E_OUTOFMEMORY - Insufficient memory | |
374 * \return E_POINTER - Null pointer | |
375 * | |
376 * \note | |
377 * Pin's Id is not the same as pin's name | |
378 * | |
379 */ | |
3056 | 380 static long STDCALL CInputPin_QueryId(IPin* This, |
381 /* [out] */ unsigned short* *Id) | |
168 | 382 { |
3056 | 383 Debug unimplemented("CInputPin_QueryId", This); |
384 return E_NOTIMPL; | |
168 | 385 } |
386 | |
22028 | 387 /** |
388 * \brief IPin::QueryAccept (determines can media type be accepted or not) | |
389 * | |
390 * \param[in] This pointer to IPin interface | |
391 * \param[in] pmt Media type to check | |
392 * | |
393 * \return S_OK - success | |
394 * \return S_FALSE - pin rejects media type | |
395 * | |
396 */ | |
3056 | 397 static long STDCALL CInputPin_QueryAccept(IPin* This, |
3130 | 398 /* [in] */ const AM_MEDIA_TYPE* pmt) |
168 | 399 { |
3056 | 400 Debug unimplemented("CInputPin_QueryAccept", This); |
168 | 401 return E_NOTIMPL; |
402 } | |
403 | |
22028 | 404 /** |
405 * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types) | |
406 * | |
407 * \param[in] This pointer to IPin interface | |
408 * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface | |
409 * | |
410 * \return S_OK - success | |
411 * \return E_OUTOFMEMORY - Insufficient memory | |
412 * \return E_POINTER - Null pointer | |
413 * | |
414 * \note | |
415 * Caller must call Release on received interface when done | |
416 * | |
417 */ | |
3056 | 418 static long STDCALL CInputPin_EnumMediaTypes(IPin* This, |
3130 | 419 /* [out] */ IEnumMediaTypes** ppEnum) |
168 | 420 { |
3056 | 421 Debug unimplemented("CInputPin_EnumMediaTypes", This); |
422 return E_NOTIMPL; | |
423 } | |
424 | |
22028 | 425 /** |
426 * \brief IPin::QueryInternalConnections (retries pin's internal connections) | |
427 * | |
428 * \param[in] This pointer to IPin interface | |
429 * \param[out] apPin Array that receives pins, internally connected to this | |
430 * \param[in,out] nPint Size of an array | |
431 * | |
432 * \return S_OK - success | |
433 * \return S_FALSE - pin rejects media type | |
434 * \return E_NOTIMPL - not implemented | |
435 * | |
436 */ | |
3056 | 437 static long STDCALL CInputPin_QueryInternalConnections(IPin* This, |
3130 | 438 /* [out] */ IPin** apPin, |
3056 | 439 /* [out][in] */ unsigned long *nPin) |
440 { | |
441 Debug unimplemented("CInputPin_QueryInternalConnections", This); | |
442 return E_NOTIMPL; | |
443 } | |
444 | |
22028 | 445 /** |
446 * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command) | |
447 * | |
448 * \param[in] This pointer to IPin interface | |
449 * | |
450 * \return S_OK - success | |
451 * \return E_UNEXPECTED - The pin is output pin | |
452 * | |
453 * \note | |
454 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, | |
455 * IMemAllocator::GetBuffer runs in different (streaming) thread then other | |
456 * methods (application thread). | |
457 * IMemoryInputPin::NewSegment runs either in streaming or application thread. | |
458 * Developer must use critical sections for thread-safing work. | |
459 * | |
460 */ | |
3056 | 461 static long STDCALL CInputPin_EndOfStream(IPin * This) |
462 { | |
463 Debug unimplemented("CInputPin_EndOfStream", This); | |
168 | 464 return E_NOTIMPL; |
465 } | |
466 | |
467 | |
22028 | 468 /** |
469 * \brief IPin::BeginFlush (begins a flush operation) | |
470 * | |
471 * \param[in] This pointer to IPin interface | |
472 * | |
473 * \return S_OK - success | |
474 * \return E_UNEXPECTED - The pin is output pin | |
475 * | |
476 */ | |
3056 | 477 static long STDCALL CInputPin_BeginFlush(IPin * This) |
168 | 478 { |
3056 | 479 Debug unimplemented("CInputPin_BeginFlush", This); |
168 | 480 return E_NOTIMPL; |
481 } | |
482 | |
483 | |
22028 | 484 /** |
485 * \brief IPin::EndFlush (ends a flush operation) | |
486 * | |
487 * \param[in] This pointer to IPin interface | |
488 * | |
489 * \return S_OK - success | |
490 * \return E_UNEXPECTED - The pin is output pin | |
491 * | |
492 */ | |
3130 | 493 static long STDCALL CInputPin_EndFlush(IPin* This) |
168 | 494 { |
3056 | 495 Debug unimplemented("CInputPin_EndFlush", This); |
168 | 496 return E_NOTIMPL; |
497 } | |
498 | |
22028 | 499 /** |
500 * \brief IPin::NewSegment (media sample received after this call grouped as segment with common | |
501 * start,stop time and rate) | |
502 * | |
503 * \param[in] This pointer to IPin interface | |
504 * \param[in] tStart start time of new segment | |
505 * \param[in] tStop end time of new segment | |
506 * \param[in] dRate rate at wich segment should be processed | |
507 * | |
508 * \return S_OK - success | |
509 * \return E_UNEXPECTED - The pin is output pin | |
510 * | |
511 */ | |
3130 | 512 static long STDCALL CInputPin_NewSegment(IPin* This, |
3056 | 513 /* [in] */ REFERENCE_TIME tStart, |
514 /* [in] */ REFERENCE_TIME tStop, | |
515 /* [in] */ double dRate) | |
168 | 516 { |
3056 | 517 Debug unimplemented("CInputPin_NewSegment", This); |
168 | 518 return E_NOTIMPL; |
1545 | 519 } |
168 | 520 |
22028 | 521 /** |
522 * \brief CInputPin destructor | |
523 * | |
524 * \param[in] This pointer to CInputPin class | |
525 * | |
526 */ | |
3056 | 527 static void CInputPin_Destroy(CInputPin* This) |
168 | 528 { |
3056 | 529 free(This->vt); |
530 free(This); | |
1545 | 531 } |
532 | |
3056 | 533 IMPLEMENT_IUNKNOWN(CInputPin) |
534 | |
22028 | 535 /** |
536 * \brief CInputPin constructor | |
537 * | |
538 * \param[in] amt media type for pin | |
539 * | |
540 * \return pointer to CInputPin if success | |
541 * \return NULL if error occured | |
542 * | |
543 */ | |
3056 | 544 CInputPin* CInputPinCreate(CBaseFilter* p, const AM_MEDIA_TYPE* amt) |
168 | 545 { |
3056 | 546 CInputPin* This = (CInputPin*) malloc(sizeof(CInputPin)); |
547 | |
3467 | 548 if (!This) |
549 return NULL; | |
550 | |
551 This->refcount = 1; | |
3056 | 552 This->parent = p; |
553 This->type = *amt; | |
554 | |
555 This->vt= (IPin_vt*) malloc(sizeof(IPin_vt)); | |
3467 | 556 |
557 if (!This->vt) | |
558 { | |
559 free(This); | |
560 return NULL; | |
561 } | |
562 | |
3056 | 563 This->vt->QueryInterface = CInputPin_QueryInterface; |
564 This->vt->AddRef = CInputPin_AddRef; | |
565 This->vt->Release = CInputPin_Release; | |
566 This->vt->Connect = CInputPin_Connect; | |
567 This->vt->ReceiveConnection = CInputPin_ReceiveConnection; | |
568 This->vt->Disconnect = CInputPin_Disconnect; | |
569 This->vt->ConnectedTo = CInputPin_ConnectedTo; | |
570 This->vt->ConnectionMediaType = CInputPin_ConnectionMediaType; | |
571 This->vt->QueryPinInfo = CInputPin_QueryPinInfo; | |
572 This->vt->QueryDirection = CInputPin_QueryDirection; | |
573 This->vt->QueryId = CInputPin_QueryId; | |
574 This->vt->QueryAccept = CInputPin_QueryAccept; | |
575 This->vt->EnumMediaTypes = CInputPin_EnumMediaTypes; | |
576 This->vt->QueryInternalConnections = CInputPin_QueryInternalConnections; | |
577 This->vt->EndOfStream = CInputPin_EndOfStream; | |
578 This->vt->BeginFlush = CInputPin_BeginFlush; | |
579 This->vt->EndFlush = CInputPin_EndFlush; | |
580 This->vt->NewSegment = CInputPin_NewSegment; | |
581 | |
582 This->interfaces[0]=IID_IUnknown; | |
583 | |
584 return This; | |
1545 | 585 } |
168 | 586 |
3056 | 587 |
588 /************* | |
589 * BaseFilter | |
590 *************/ | |
591 | |
592 static long STDCALL CBaseFilter_GetClassID(IBaseFilter * This, | |
593 /* [out] */ CLSID *pClassID) | |
168 | 594 { |
3056 | 595 Debug unimplemented("CBaseFilter_GetClassID", This); |
168 | 596 return E_NOTIMPL; |
1545 | 597 } |
168 | 598 |
22028 | 599 /** |
600 * \brief IMediaFilter::Stop (stops the filter) | |
601 * | |
602 * \param[in] This pointer to IBaseFilter interface | |
603 * | |
604 * \return S_OK success | |
605 * \return S_FALSE transition is not complete | |
606 * | |
607 * \remarks | |
608 * When filter is stopped it does onot deliver or process any samples and rejects any samples | |
609 * from upstream filter. | |
610 * Transition may be asynchronous. In this case method should return S_FALSE. | |
611 * Method always sets filter's state to State_Stopped even if error occured. | |
612 * | |
613 */ | |
3056 | 614 static long STDCALL CBaseFilter_Stop(IBaseFilter* This) |
168 | 615 { |
3056 | 616 Debug unimplemented("CBaseFilter_Stop", This); |
168 | 617 return E_NOTIMPL; |
1545 | 618 } |
168 | 619 |
22028 | 620 /** |
621 * \brief IMediaFilter::Pause (pauses filter) | |
622 * | |
623 * \param[in] This pointer to IBaseFilter interface | |
624 * | |
625 * \return S_OK success | |
626 * \return S_FALSE transition is not complete | |
627 * | |
628 * \remarks | |
629 * When filter is paused it can receive, process and deliver samples. | |
630 * Live source filters do not deliver any samples while paused. | |
631 * Transition may be asynchronous. In this case method should return S_FALSE. | |
632 * Method always sets filter's state to State_Stopped even if error occured. | |
633 * | |
634 */ | |
3056 | 635 static long STDCALL CBaseFilter_Pause(IBaseFilter* This) |
168 | 636 { |
3056 | 637 Debug unimplemented("CBaseFilter_Pause", This); |
638 return E_NOTIMPL; | |
639 } | |
640 | |
22028 | 641 /** |
642 * \brief IMediaFilter::Run (runs the filter) | |
643 * | |
644 * \param[in] This pointer to IBaseFilter interface | |
645 * \param[in] tStart Reference time corresponding to stream time 0. | |
646 * | |
647 * \return S_OK success | |
648 * \return S_FALSE transition is not complete | |
649 * | |
650 * \remarks | |
651 * When filter is running it can receive, process and deliver samples. Source filters | |
652 * generatesnew samples, and renderers renders them. | |
653 * Stream time is calculated as the current reference time minus tStart. | |
654 * Graph Manager sets tStart slightly in the future according to graph latency. | |
655 * | |
656 */ | |
3056 | 657 static long STDCALL CBaseFilter_Run(IBaseFilter* This, REFERENCE_TIME tStart) |
658 { | |
659 Debug unimplemented("CBaseFilter_Run", This); | |
168 | 660 return E_NOTIMPL; |
1545 | 661 } |
168 | 662 |
22028 | 663 /** |
664 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused)) | |
665 * | |
666 * \param[in] This pointer to IBaseFilter interface | |
667 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass | |
668 * INFINITE. | |
669 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration. | |
670 * | |
671 * \return S_OK success | |
672 * \return E_POINTER Null pointer | |
673 * \return VFW_S_STATE_INTERMEDATE Intermediate state | |
674 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data. | |
675 * | |
676 */ | |
3056 | 677 static long STDCALL CBaseFilter_GetState(IBaseFilter* This, |
678 /* [in] */ unsigned long dwMilliSecsTimeout, | |
679 // /* [out] */ FILTER_STATE *State) | |
680 void* State) | |
168 | 681 { |
3056 | 682 Debug unimplemented("CBaseFilter_GetState", This); |
683 return E_NOTIMPL; | |
1545 | 684 } |
168 | 685 |
22028 | 686 /** |
687 * \brief IMediaFilter::SetSyncSource (sets the reference clock) | |
688 * | |
689 * \param[in] This pointer to IBaseFilter interface | |
690 * \param[in] pClock IReferenceClock interface of reference clock | |
691 * | |
692 * \return S_OK success | |
693 * \return apripriate error otherwise | |
694 * | |
695 */ | |
3056 | 696 static long STDCALL CBaseFilter_SetSyncSource(IBaseFilter* This, |
697 /* [in] */ IReferenceClock *pClock) | |
698 { | |
699 Debug unimplemented("CBaseFilter_SetSyncSource", This); | |
700 return E_NOTIMPL; | |
701 } | |
1545 | 702 |
22028 | 703 /** |
704 * \brief IMediafilter::GetSyncSource (gets current reference clock) | |
705 * | |
706 * \param[in] This pointer to IBaseFilter interface | |
707 * \param[out] pClock address of variable that receives pointer to clock's | |
708 * IReferenceClock interface | |
709 * | |
710 * \return S_OK success | |
711 * \return E_POINTER Null pointer | |
712 * | |
713 */ | |
3056 | 714 static long STDCALL CBaseFilter_GetSyncSource(IBaseFilter* This, |
715 /* [out] */ IReferenceClock **pClock) | |
168 | 716 { |
3056 | 717 Debug unimplemented("CBaseFilter_GetSyncSource", This); |
168 | 718 return E_NOTIMPL; |
1545 | 719 } |
168 | 720 |
1545 | 721 |
22028 | 722 /** |
723 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter) | |
724 * | |
725 * \param[in] This pointer to IBaseFilter interface | |
726 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface | |
727 * | |
728 * \return S_OK success | |
729 * \return E_OUTOFMEMORY Insufficient memory | |
730 * \return E_POINTER Null pointer | |
731 * | |
732 */ | |
3056 | 733 static long STDCALL CBaseFilter_EnumPins(IBaseFilter* This, |
734 /* [out] */ IEnumPins **ppEnum) | |
735 { | |
736 Debug printf("CBaseFilter_EnumPins(%p) called\n", This); | |
737 *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter*)This)->pin, ((CBaseFilter*)This)->unused_pin); | |
738 return 0; | |
739 } | |
740 | |
22028 | 741 /** |
742 * \brief IBaseFilter::FindPin (retrieves the pin with specified id) | |
743 * | |
744 * \param[in] This pointer to IBaseFilter interface | |
745 * \param[in] Id constant wide string, containing pin id | |
746 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface | |
747 * | |
748 * \return S_OK success | |
749 * \return E_POINTER Null pointer | |
750 * \return VFW_E_NOT_FOUND Could not find a pin with specified id | |
751 * | |
752 * \note | |
753 * Be sure to release the interface after use. | |
754 * | |
755 */ | |
3056 | 756 static long STDCALL CBaseFilter_FindPin(IBaseFilter* This, |
757 /* [string][in] */ const unsigned short* Id, | |
758 /* [out] */ IPin **ppPin) | |
168 | 759 { |
3056 | 760 Debug unimplemented("CBaseFilter_FindPin\n", This); |
761 return E_NOTIMPL; | |
762 } | |
763 | |
22028 | 764 /** |
765 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter) | |
766 * | |
767 * \param[in] This pointer to IBaseFilter interface | |
768 * \param[out] pInfo pointer to FILTER_INFO structure | |
769 * | |
770 * \return S_OK success | |
771 * \return E_POINTER Null pointer | |
772 * | |
773 * \note | |
774 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use. | |
775 * | |
776 */ | |
3130 | 777 static long STDCALL CBaseFilter_QueryFilterInfo(IBaseFilter* This, |
3056 | 778 // /* [out] */ FILTER_INFO *pInfo) |
779 void* pInfo) | |
780 { | |
781 Debug unimplemented("CBaseFilter_QueryFilterInfo", This); | |
782 return E_NOTIMPL; | |
783 } | |
784 | |
22028 | 785 /** |
786 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph) | |
787 * | |
788 * \param[in] This pointer to IBaseFilter interface | |
789 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph | |
790 * \param[in] pName pointer to wide character string that specifies a name for the filter | |
791 * | |
792 * \return S_OK success | |
793 * \return apropriate error code otherwise | |
794 * | |
795 * \remarks | |
796 * Filter should not call to graph's AddRef method. | |
797 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with | |
798 * the value NULL. | |
799 * | |
800 */ | |
3130 | 801 static long STDCALL CBaseFilter_JoinFilterGraph(IBaseFilter* This, |
802 /* [in] */ IFilterGraph* pGraph, | |
3056 | 803 /* [string][in] */ const unsigned short* pName) |
804 { | |
805 Debug unimplemented("CBaseFilter_JoinFilterGraph", This); | |
806 return E_NOTIMPL; | |
807 } | |
808 | |
22028 | 809 /** |
810 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info) | |
811 * | |
812 * \param[in] This pointer to IBaseFilter interface | |
813 * \param[out] address of variable that receives pointer to a string containing vendor info | |
814 * | |
815 * \return S_OK success | |
816 * \return E_POINTER Null pointer | |
817 * \return E_NOTIMPL Not implemented | |
818 * | |
819 * \remarks | |
820 * Call to CoTaskMemFree to free memory allocated for string | |
821 * | |
822 */ | |
3130 | 823 static long STDCALL CBaseFilter_QueryVendorInfo(IBaseFilter* This, |
824 /* [string][out] */ unsigned short** pVendorInfo) | |
3056 | 825 { |
826 Debug unimplemented("CBaseFilter_QueryVendorInfo", This); | |
168 | 827 return E_NOTIMPL; |
1545 | 828 } |
168 | 829 |
22028 | 830 /** |
831 * \brief CBaseFilter::GetPin (gets used pin) | |
832 * | |
833 * \param[in] This pointer to CBaseFilter object | |
834 * | |
835 * \return pointer to used pin's IPin interface | |
836 * | |
837 */ | |
3056 | 838 static IPin* CBaseFilter_GetPin(CBaseFilter* This) |
839 { | |
840 return This->pin; | |
841 } | |
1545 | 842 |
22028 | 843 /** |
844 * \brief CBaseFilter::GetUnusedPin (gets used pin) | |
845 * | |
846 * \param[in] This pointer to CBaseFilter object | |
847 * | |
848 * \return pointer to unused pin's IPin interface | |
849 * | |
850 */ | |
3056 | 851 static IPin* CBaseFilter_GetUnusedPin(CBaseFilter* This) |
168 | 852 { |
3056 | 853 return This->unused_pin; |
854 } | |
855 | |
22028 | 856 /** |
857 * \brief CBaseFilter destructor | |
858 * | |
859 * \param[in] This pointer to CBaseFilter object | |
860 * | |
861 */ | |
3056 | 862 static void CBaseFilter_Destroy(CBaseFilter* This) |
863 { | |
3467 | 864 if (This->vt) |
865 free(This->vt); | |
866 if (This->pin) | |
867 This->pin->vt->Release((IUnknown*)This->pin); | |
868 if (This->unused_pin) | |
869 This->unused_pin->vt->Release((IUnknown*)This->unused_pin); | |
3056 | 870 free(This); |
1545 | 871 } |
168 | 872 |
3056 | 873 IMPLEMENT_IUNKNOWN(CBaseFilter) |
1545 | 874 |
22028 | 875 /** |
876 * \brief CBaseFilter constructor | |
877 * | |
878 * \param[in] type Pointer to media type for connection | |
879 * \param[in] parent Pointer to parent CBaseFilter2 object | |
880 * | |
881 * \return pointer to CBaseFilter object or NULL if error occured | |
882 * | |
883 */ | |
3056 | 884 CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* type, CBaseFilter2* parent) |
168 | 885 { |
3056 | 886 CBaseFilter* This = (CBaseFilter*) malloc(sizeof(CBaseFilter)); |
3467 | 887 if (!This) |
888 return NULL; | |
889 | |
3056 | 890 This->refcount = 1; |
891 | |
892 This->pin = (IPin*) CInputPinCreate(This, type); | |
893 This->unused_pin = (IPin*) CRemotePinCreate(This, parent->GetPin(parent)); | |
894 | |
895 This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); | |
3467 | 896 if (!This->vt || !This->pin || !This->unused_pin) |
897 { | |
898 CBaseFilter_Destroy(This); | |
899 return NULL; | |
900 } | |
901 | |
3056 | 902 This->vt->QueryInterface = CBaseFilter_QueryInterface; |
903 This->vt->AddRef = CBaseFilter_AddRef; | |
904 This->vt->Release = CBaseFilter_Release; | |
905 This->vt->GetClassID = CBaseFilter_GetClassID; | |
906 This->vt->Stop = CBaseFilter_Stop; | |
907 This->vt->Pause = CBaseFilter_Pause; | |
908 This->vt->Run = CBaseFilter_Run; | |
909 This->vt->GetState = CBaseFilter_GetState; | |
910 This->vt->SetSyncSource = CBaseFilter_SetSyncSource; | |
911 This->vt->GetSyncSource = CBaseFilter_GetSyncSource; | |
912 This->vt->EnumPins = CBaseFilter_EnumPins; | |
913 This->vt->FindPin = CBaseFilter_FindPin; | |
914 This->vt->QueryFilterInfo = CBaseFilter_QueryFilterInfo; | |
915 This->vt->JoinFilterGraph = CBaseFilter_JoinFilterGraph; | |
916 This->vt->QueryVendorInfo = CBaseFilter_QueryVendorInfo; | |
917 | |
918 This->interfaces[0] = IID_IUnknown; | |
919 This->interfaces[1] = IID_IBaseFilter; | |
920 | |
921 This->GetPin = CBaseFilter_GetPin; | |
922 This->GetUnusedPin = CBaseFilter_GetUnusedPin; | |
923 | |
924 return This; | |
1545 | 925 } |
168 | 926 |
927 | |
3056 | 928 /************** |
929 * BaseFilter2 | |
930 **************/ | |
168 | 931 |
932 | |
3130 | 933 static long STDCALL CBaseFilter2_GetClassID(IBaseFilter* This, |
934 /* [out] */ CLSID* pClassID) | |
168 | 935 { |
3056 | 936 Debug unimplemented("CBaseFilter2_GetClassID", This); |
168 | 937 return E_NOTIMPL; |
1545 | 938 } |
168 | 939 |
22028 | 940 /** |
941 * \brief IMediaFilter::Stop (stops the filter) | |
942 * | |
943 * \param[in] This pointer to IBaseFilter interface | |
944 * | |
945 * \return S_OK success | |
946 * \return S_FALSE transition is not complete | |
947 * | |
948 * \remarks | |
949 * When filter is stopped it does onot deliver or process any samples and rejects any samples | |
950 * from upstream filter. | |
951 * Transition may be asynchronous. In this case method should return S_FALSE. | |
952 * Method always sets filter's state to State_Stopped even if error occured. | |
953 * | |
954 */ | |
3130 | 955 static long STDCALL CBaseFilter2_Stop(IBaseFilter* This) |
168 | 956 { |
3056 | 957 Debug unimplemented("CBaseFilter2_Stop", This); |
168 | 958 return E_NOTIMPL; |
1545 | 959 } |
168 | 960 |
22028 | 961 /** |
962 * \brief IMediaFilter::Pause (pauses filter) | |
963 * | |
964 * \param[in] This pointer to IBaseFilter interface | |
965 * | |
966 * \return S_OK success | |
967 * \return S_FALSE transition is not complete | |
968 * | |
969 * \remarks | |
970 * When filter is paused it can receive, process and deliver samples. | |
971 * Live source filters do not deliver any samples while paused. | |
972 * Transition may be asynchronous. In this case method should return S_FALSE. | |
973 * Method always sets filter's state to State_Stopped even if error occured. | |
974 * | |
975 */ | |
3130 | 976 static long STDCALL CBaseFilter2_Pause(IBaseFilter* This) |
168 | 977 { |
3056 | 978 Debug unimplemented("CBaseFilter2_Pause", This); |
168 | 979 return E_NOTIMPL; |
1545 | 980 } |
981 | |
22028 | 982 /** |
983 * \brief IMediaFilter::Run (runs the filter) | |
984 * | |
985 * \param[in] This pointer to IBaseFilter interface | |
986 * \param[in] tStart Reference time corresponding to stream time 0. | |
987 * | |
988 * \return S_OK success | |
989 * \return S_FALSE transition is not complete | |
990 * | |
991 * \remarks | |
992 * When filter is running it can receive, process and deliver samples. Source filters | |
993 * generatesnew samples, and renderers renders them. | |
994 * Stream time is calculated as the current reference time minus tStart. | |
995 * Graph Manager sets tStart slightly in the future according to graph latency. | |
996 * | |
997 */ | |
3130 | 998 static long STDCALL CBaseFilter2_Run(IBaseFilter* This, REFERENCE_TIME tStart) |
168 | 999 { |
3056 | 1000 Debug unimplemented("CBaseFilter2_Run", This); |
168 | 1001 return E_NOTIMPL; |
1545 | 1002 } |
168 | 1003 |
1545 | 1004 |
22028 | 1005 /** |
1006 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused)) | |
1007 * | |
1008 * \param[in] This pointer to IBaseFilter interface | |
1009 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass | |
1010 * INFINITE. | |
1011 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration. | |
1012 * | |
1013 * \return S_OK success | |
1014 * \return E_POINTER Null pointer | |
1015 * \return VFW_S_STATE_INTERMEDATE Intermediate state | |
1016 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data. | |
1017 * | |
1018 */ | |
3056 | 1019 static long STDCALL CBaseFilter2_GetState(IBaseFilter* This, |
1020 /* [in] */ unsigned long dwMilliSecsTimeout, | |
1021 // /* [out] */ FILTER_STATE *State) | |
1022 void* State) | |
1023 { | |
1024 Debug unimplemented("CBaseFilter2_GetState", This); | |
1025 return E_NOTIMPL; | |
1026 } | |
1027 | |
22028 | 1028 /** |
1029 * \brief IMediaFilter::SetSyncSource (sets the reference clock) | |
1030 * | |
1031 * \param[in] This pointer to IBaseFilter interface | |
1032 * \param[in] pClock IReferenceClock interface of reference clock | |
1033 * | |
1034 * \return S_OK success | |
1035 * \return apripriate error otherwise | |
1036 * | |
1037 */ | |
3056 | 1038 static long STDCALL CBaseFilter2_SetSyncSource(IBaseFilter* This, |
1039 /* [in] */ IReferenceClock* pClock) | |
1040 { | |
1041 Debug unimplemented("CBaseFilter2_SetSyncSource", This); | |
1042 return E_NOTIMPL; | |
1043 } | |
1044 | |
22028 | 1045 /** |
1046 * \brief IMediafilter::GetSyncSource (gets current reference clock) | |
1047 * | |
1048 * \param[in] This pointer to IBaseFilter interface | |
1049 * \param[out] pClock address of variable that receives pointer to clock's | |
1050 * IReferenceClock interface | |
1051 * | |
1052 * \return S_OK success | |
1053 * \return E_POINTER Null pointer | |
1054 * | |
1055 */ | |
3056 | 1056 static long STDCALL CBaseFilter2_GetSyncSource(IBaseFilter* This, |
1057 /* [out] */ IReferenceClock** pClock) | |
1058 { | |
1059 Debug unimplemented("CBaseFilter2_GetSyncSource", This); | |
1060 return E_NOTIMPL; | |
1061 } | |
1062 | |
22028 | 1063 /** |
1064 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter) | |
1065 * | |
1066 * \param[in] This pointer to IBaseFilter interface | |
1067 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface | |
1068 * | |
1069 * \return S_OK success | |
1070 * \return E_OUTOFMEMORY Insufficient memory | |
1071 * \return E_POINTER Null pointer | |
1072 * | |
1073 */ | |
3056 | 1074 static long STDCALL CBaseFilter2_EnumPins(IBaseFilter* This, |
1075 /* [out] */ IEnumPins** ppEnum) | |
168 | 1076 { |
3056 | 1077 Debug printf("CBaseFilter2_EnumPins(%p) called\n", This); |
1078 *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter2*)This)->pin, 0); | |
1079 return 0; | |
1080 } | |
1081 | |
22028 | 1082 /** |
1083 * \brief IBaseFilter::FindPin (retrieves the pin with specified id) | |
1084 * | |
1085 * \param[in] This pointer to IBaseFilter interface | |
1086 * \param[in] Id constant wide string, containing pin id | |
1087 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface | |
1088 * | |
1089 * \return S_OK success | |
1090 * \return E_POINTER Null pointer | |
1091 * \return VFW_E_NOT_FOUND Could not find a pin with specified id | |
1092 * | |
1093 * \note | |
1094 * Be sure to release the interface after use. | |
1095 * | |
1096 */ | |
3056 | 1097 static long STDCALL CBaseFilter2_FindPin(IBaseFilter* This, |
1098 /* [string][in] */ const unsigned short* Id, | |
1099 /* [out] */ IPin** ppPin) | |
1100 { | |
1101 Debug unimplemented("CBaseFilter2_FindPin", This); | |
1102 return E_NOTIMPL; | |
1103 } | |
1104 | |
22028 | 1105 /** |
1106 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter) | |
1107 * | |
1108 * \param[in] This pointer to IBaseFilter interface | |
1109 * \param[out] pInfo pointer to FILTER_INFO structure | |
1110 * | |
1111 * \return S_OK success | |
1112 * \return E_POINTER Null pointer | |
1113 * | |
1114 * \note | |
1115 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use. | |
1116 * | |
1117 */ | |
3056 | 1118 static long STDCALL CBaseFilter2_QueryFilterInfo(IBaseFilter* This, |
1119 // /* [out] */ FILTER_INFO *pInfo) | |
1120 void* pInfo) | |
1121 { | |
1122 Debug unimplemented("CBaseFilter2_QueryFilterInfo", This); | |
1123 return E_NOTIMPL; | |
1124 } | |
1125 | |
22028 | 1126 /** |
1127 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph) | |
1128 * | |
1129 * \param[in] This pointer to IBaseFilter interface | |
1130 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph | |
1131 * \param[in] pName pointer to wide character string that specifies a name for the filter | |
1132 * | |
1133 * \return S_OK success | |
1134 * \return apropriate error code otherwise | |
1135 * | |
1136 * \remarks | |
1137 * Filter should not call to graph's AddRef method. | |
1138 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with | |
1139 * the value NULL. | |
1140 * | |
1141 */ | |
3056 | 1142 static long STDCALL CBaseFilter2_JoinFilterGraph(IBaseFilter* This, |
1143 /* [in] */ IFilterGraph* pGraph, | |
1144 /* [string][in] */ | |
1145 const unsigned short* pName) | |
1146 { | |
1147 Debug unimplemented("CBaseFilter2_JoinFilterGraph", This); | |
168 | 1148 return E_NOTIMPL; |
1545 | 1149 } |
168 | 1150 |
22028 | 1151 /** |
1152 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info) | |
1153 * | |
1154 * \param[in] This pointer to IBaseFilter interface | |
1155 * \param[out] address of variable that receives pointer to a string containing vendor info | |
1156 * | |
1157 * \return S_OK success | |
1158 * \return E_POINTER Null pointer | |
1159 * \return E_NOTIMPL Not implemented | |
1160 * | |
1161 * \remarks | |
1162 * Call to CoTaskMemFree to free memory allocated for string | |
1163 * | |
1164 */ | |
3056 | 1165 static long STDCALL CBaseFilter2_QueryVendorInfo(IBaseFilter* This, |
1166 /* [string][out] */ | |
1167 unsigned short** pVendorInfo) | |
168 | 1168 { |
3056 | 1169 Debug unimplemented("CBaseFilter2_QueryVendorInfo", This); |
168 | 1170 return E_NOTIMPL; |
1545 | 1171 } |
168 | 1172 |
22028 | 1173 /** |
1174 * \brief CBaseFilter2::GetPin (gets used pin) | |
1175 * | |
1176 * \param[in] This pointer to CBaseFilter2 object | |
1177 * | |
1178 * \return pointer to used pin's IPin interface | |
1179 * | |
1180 */ | |
3056 | 1181 static IPin* CBaseFilter2_GetPin(CBaseFilter2* This) |
1182 { | |
1183 return This->pin; | |
1184 } | |
1545 | 1185 |
22028 | 1186 /** |
1187 * \brief CBaseFilter2 destructor | |
1188 * | |
1189 * \param[in] This pointer to CBaseFilter2 object | |
1190 * | |
1191 */ | |
3056 | 1192 static void CBaseFilter2_Destroy(CBaseFilter2* This) |
168 | 1193 { |
3130 | 1194 Debug printf("CBaseFilter2_Destroy(%p) called\n", This); |
3467 | 1195 if (This->pin) |
1196 This->pin->vt->Release((IUnknown*) This->pin); | |
1197 if (This->vt) | |
1198 free(This->vt); | |
3056 | 1199 free(This); |
1545 | 1200 } |
168 | 1201 |
3056 | 1202 IMPLEMENT_IUNKNOWN(CBaseFilter2) |
1545 | 1203 |
3056 | 1204 static GUID CBaseFilter2_interf1 = |
1205 {0x76c61a30, 0xebe1, 0x11cf, {0x89, 0xf9, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb}}; | |
22028 | 1206 /// IID_IAMNetShowPreroll |
3056 | 1207 static GUID CBaseFilter2_interf2 = |
1208 {0xaae7e4e2, 0x6388, 0x11d1, {0x8d, 0x93, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2}}; | |
22028 | 1209 /// IID_IAMRebuild |
3056 | 1210 static GUID CBaseFilter2_interf3 = |
1211 {0x02ef04dd, 0x7580, 0x11d1, {0xbe, 0xce, 0x00, 0xc0, 0x4f, 0xb6, 0xe9, 0x37}}; | |
1212 | |
22028 | 1213 /** |
1214 * \brief CBaseFilter2 constructor | |
1215 * | |
1216 * \return pointer to CBaseFilter2 object or NULL if error occured | |
1217 * | |
1218 */ | |
3056 | 1219 CBaseFilter2* CBaseFilter2Create() |
168 | 1220 { |
3056 | 1221 CBaseFilter2* This = (CBaseFilter2*) malloc(sizeof(CBaseFilter2)); |
1222 | |
3467 | 1223 if (!This) |
1224 return NULL; | |
1225 | |
3056 | 1226 This->refcount = 1; |
1227 This->pin = (IPin*) CRemotePin2Create(This); | |
1228 | |
1229 This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); | |
3467 | 1230 |
1231 if (!This->pin || !This->vt) | |
1232 { | |
1233 CBaseFilter2_Destroy(This); | |
1234 return NULL; | |
1235 } | |
1236 | |
3056 | 1237 memset(This->vt, 0, sizeof(IBaseFilter_vt)); |
1238 This->vt->QueryInterface = CBaseFilter2_QueryInterface; | |
1239 This->vt->AddRef = CBaseFilter2_AddRef; | |
1240 This->vt->Release = CBaseFilter2_Release; | |
1241 This->vt->GetClassID = CBaseFilter2_GetClassID; | |
1242 This->vt->Stop = CBaseFilter2_Stop; | |
1243 This->vt->Pause = CBaseFilter2_Pause; | |
1244 This->vt->Run = CBaseFilter2_Run; | |
1245 This->vt->GetState = CBaseFilter2_GetState; | |
1246 This->vt->SetSyncSource = CBaseFilter2_SetSyncSource; | |
1247 This->vt->GetSyncSource = CBaseFilter2_GetSyncSource; | |
1248 This->vt->EnumPins = CBaseFilter2_EnumPins; | |
1249 This->vt->FindPin = CBaseFilter2_FindPin; | |
1250 This->vt->QueryFilterInfo = CBaseFilter2_QueryFilterInfo; | |
1251 This->vt->JoinFilterGraph = CBaseFilter2_JoinFilterGraph; | |
1252 This->vt->QueryVendorInfo = CBaseFilter2_QueryVendorInfo; | |
1253 | |
1254 This->GetPin = CBaseFilter2_GetPin; | |
1255 | |
1256 This->interfaces[0] = IID_IUnknown; | |
1257 This->interfaces[1] = IID_IBaseFilter; | |
1258 This->interfaces[2] = CBaseFilter2_interf1; | |
1259 This->interfaces[3] = CBaseFilter2_interf2; | |
1260 This->interfaces[4] = CBaseFilter2_interf3; | |
1261 | |
1262 return This; | |
1545 | 1263 } |
168 | 1264 |
1545 | 1265 |
3056 | 1266 /************* |
1267 * CRemotePin | |
1268 *************/ | |
1545 | 1269 |
168 | 1270 |
22028 | 1271 /** |
1272 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist) | |
1273 * | |
1274 * \param[in] This pointer to IPin interface | |
1275 * \param[out] pPin pointer to remote pin's IPin interface | |
1276 * | |
1277 * \return S_OK - success | |
1278 * \return E_POINTER - Null pointer | |
1279 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
1280 * | |
1281 * \note | |
1282 * Caller must call Release on received IPin, when done | |
1283 */ | |
3056 | 1284 static long STDCALL CRemotePin_ConnectedTo(IPin* This, /* [out] */ IPin** pPin) |
168 | 1285 { |
3056 | 1286 Debug printf("CRemotePin_ConnectedTo(%p) called\n", This); |
1545 | 1287 if (!pPin) |
1288 return E_INVALIDARG; | |
3056 | 1289 *pPin = ((CRemotePin*)This)->remote_pin; |
1545 | 1290 (*pPin)->vt->AddRef((IUnknown*)(*pPin)); |
1291 return 0; | |
1292 } | |
168 | 1293 |
22028 | 1294 /** |
1295 * \brief IPin::QueryDirection (retrieves pin direction) | |
1296 * | |
1297 * \param[in] This pointer to IPin interface | |
1298 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) | |
1299 * | |
1300 * \return S_OK - success | |
1301 * \return E_POINTER - Null pointer | |
1302 * | |
1303 */ | |
3056 | 1304 static long STDCALL CRemotePin_QueryDirection(IPin* This, |
3130 | 1305 /* [out] */ PIN_DIRECTION* pPinDir) |
1545 | 1306 { |
3056 | 1307 Debug printf("CRemotePin_QueryDirection(%p) called\n", This); |
1545 | 1308 if (!pPinDir) |
1309 return E_INVALIDARG; | |
1310 *pPinDir=PINDIR_INPUT; | |
1311 return 0; | |
1312 } | |
1313 | |
22028 | 1314 /** |
1315 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist) | |
1316 * | |
1317 * \param[in] This pointer to IPin interface | |
1318 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type | |
1319 * | |
1320 * \return S_OK - success | |
1321 * \return E_POINTER - Null pointer | |
1322 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
1323 * | |
1324 */ | |
1545 | 1325 static long STDCALL CRemotePin_ConnectionMediaType(IPin* This, /* [out] */ AM_MEDIA_TYPE* pmt) |
168 | 1326 { |
3056 | 1327 Debug unimplemented("CRemotePin_ConnectionMediaType", This); |
168 | 1328 return E_NOTIMPL; |
1329 } | |
1330 | |
22028 | 1331 /** |
1332 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
1333 * | |
1334 * \param[in] This pointer to IPin interface | |
1335 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
1336 * | |
1337 * \return S_OK - success | |
1338 * \return E_POINTER - Null pointer | |
1339 * | |
1340 * \note | |
1341 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
1342 * | |
1343 */ | |
1545 | 1344 static long STDCALL CRemotePin_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO* pInfo) |
168 | 1345 { |
1545 | 1346 CBaseFilter* lparent = ((CRemotePin*)This)->parent; |
3056 | 1347 Debug printf("CRemotePin_QueryPinInfo(%p) called\n", This); |
1348 pInfo->dir= PINDIR_INPUT; | |
1349 pInfo->pFilter = (IBaseFilter*) lparent; | |
1545 | 1350 lparent->vt->AddRef((IUnknown*)lparent); |
1351 pInfo->achName[0]=0; | |
1352 return 0; | |
1353 } | |
1354 | |
22028 | 1355 /** |
1356 * \brief CRemotePin destructor | |
1357 * | |
1358 * \param[in] This pointer to CRemotePin object | |
1359 * | |
1360 */ | |
3056 | 1361 static void CRemotePin_Destroy(CRemotePin* This) |
1362 { | |
1363 Debug printf("CRemotePin_Destroy(%p) called\n", This); | |
1364 free(This->vt); | |
1365 free(This); | |
1366 } | |
1367 | |
1368 IMPLEMENT_IUNKNOWN(CRemotePin) | |
1369 | |
22028 | 1370 /** |
1371 * \brief CRemotePin constructor | |
1372 * | |
1373 * \param[in] pt parent filter | |
1374 * \param[in] rpin remote pin | |
1375 * | |
1376 * \return pointer to CRemotePin or NULL if error occured | |
1377 * | |
1378 */ | |
3056 | 1379 CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin) |
1380 { | |
1381 CRemotePin* This = (CRemotePin*) malloc(sizeof(CRemotePin)); | |
3467 | 1382 |
1383 if (!This) | |
1384 return NULL; | |
1385 | |
3056 | 1386 Debug printf("CRemotePinCreate() called -> %p\n", This); |
1387 | |
1388 This->parent = pt; | |
1389 This->remote_pin = rpin; | |
1390 This->refcount = 1; | |
1391 | |
1392 This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); | |
3467 | 1393 |
1394 if (!This->vt) | |
1395 { | |
1396 free(This); | |
1397 return NULL; | |
1398 } | |
1399 | |
3056 | 1400 memset(This->vt, 0, sizeof(IPin_vt)); |
1401 This->vt->QueryInterface = CRemotePin_QueryInterface; | |
1402 This->vt->AddRef = CRemotePin_AddRef; | |
1403 This->vt->Release = CRemotePin_Release; | |
1404 This->vt->QueryDirection = CRemotePin_QueryDirection; | |
1405 This->vt->ConnectedTo = CRemotePin_ConnectedTo; | |
1406 This->vt->ConnectionMediaType = CRemotePin_ConnectionMediaType; | |
1407 This->vt->QueryPinInfo = CRemotePin_QueryPinInfo; | |
1408 | |
1409 This->interfaces[0] = IID_IUnknown; | |
1410 | |
1411 return This; | |
1412 } | |
1413 | |
1414 | |
1415 /************* | |
3130 | 1416 * CRemotePin2 |
3056 | 1417 *************/ |
1418 | |
1545 | 1419 |
22028 | 1420 /** |
1421 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
1422 * | |
1423 * \param[in] This pointer to IPin interface | |
1424 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
1425 * | |
1426 * \return S_OK - success | |
1427 * \return E_POINTER - Null pointer | |
1428 * | |
1429 * \note | |
1430 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
1431 * | |
1432 */ | |
3130 | 1433 static long STDCALL CRemotePin2_QueryPinInfo(IPin* This, |
1434 /* [out] */ PIN_INFO* pInfo) | |
1545 | 1435 { |
1436 CBaseFilter2* lparent=((CRemotePin2*)This)->parent; | |
3056 | 1437 Debug printf("CRemotePin2_QueryPinInfo(%p) called\n", This); |
1545 | 1438 pInfo->pFilter=(IBaseFilter*)lparent; |
1439 lparent->vt->AddRef((IUnknown*)lparent); | |
1440 pInfo->dir=PINDIR_OUTPUT; | |
168 | 1441 pInfo->achName[0]=0; |
1442 return 0; | |
1443 } | |
1545 | 1444 |
22028 | 1445 /** |
1446 * \brief CremotePin2 destructor | |
1447 * | |
1448 * \param This pointer to CRemotePin2 object | |
1449 * | |
1450 * FIXME - not being released! | |
1451 */ | |
3056 | 1452 static void CRemotePin2_Destroy(CRemotePin2* This) |
1545 | 1453 { |
3056 | 1454 Debug printf("CRemotePin2_Destroy(%p) called\n", This); |
1455 free(This->vt); | |
1456 free(This); | |
1545 | 1457 } |
1458 | |
3056 | 1459 IMPLEMENT_IUNKNOWN(CRemotePin2) |
1460 | |
22028 | 1461 /** |
1462 * \brief CRemotePin2 contructor | |
1463 * | |
1464 * \param[in] p pointer to parent CBaseFilter2 object | |
1465 * | |
1466 * \return pointer to CRemotePin2 object or NULL if error occured | |
1467 * | |
1468 */ | |
3056 | 1469 CRemotePin2* CRemotePin2Create(CBaseFilter2* p) |
1545 | 1470 { |
3056 | 1471 CRemotePin2* This = (CRemotePin2*) malloc(sizeof(CRemotePin2)); |
3467 | 1472 |
1473 if (!This) | |
1474 return NULL; | |
1475 | |
3056 | 1476 Debug printf("CRemotePin2Create() called -> %p\n", This); |
1477 | |
1478 This->parent = p; | |
1479 This->refcount = 1; | |
1480 | |
1481 This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); | |
3467 | 1482 |
1483 if (!This->vt) | |
1484 { | |
1485 free(This); | |
1486 return NULL; | |
1487 } | |
1488 | |
3056 | 1489 memset(This->vt, 0, sizeof(IPin_vt)); |
1490 This->vt->QueryInterface = CRemotePin2_QueryInterface; | |
1491 This->vt->AddRef = CRemotePin2_AddRef; | |
1492 This->vt->Release = CRemotePin2_Release; | |
1493 This->vt->QueryPinInfo = CRemotePin2_QueryPinInfo; | |
1494 | |
1495 This->interfaces[0] = IID_IUnknown; | |
1496 | |
1497 return This; | |
1545 | 1498 } |