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