Mercurial > mplayer.hg
annotate loader/dshow/inputpin.c @ 33263:5f527a9a9521
Add an exit function.
This function will allow performing clean-up operations.
(MPlayer calls guiDone() before exiting, but only if the GUI has been
initialized, i.e. if guiInit() has been called successfully. Any
exit_player()/exit_player_with_rc() after GUI's cfg_read() until
guiInit(), or any exit_player() during guiInit() itself will end the GUI
without calling guiDone(). This exit function will at least handle
abortions during guiInit() itself. It will be called twice in case of an
guiExit() after GUI initialization - first directly, next by guiDone()
via MPlayer's exit_player_with_rc().)
author | ib |
---|---|
date | Tue, 03 May 2011 12:19:22 +0000 |
parents | 8fa2f43cb760 |
children |
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 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9964
diff
changeset
|
5 |
168 | 6 #include "inputpin.h" |
22305
3d1b23cf3d08
Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
voroshil
parents:
22028
diff
changeset
|
7 #include "mediatype.h" |
30170
008338d7679f
Drop -Iloader from CPPFLAGS for the loader subdirectory.
diego
parents:
29263
diff
changeset
|
8 #include "loader/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 { |
30702 | 170 CEnumPins* This = malloc(sizeof(CEnumPins)); |
3056 | 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 | |
30702 | 180 This->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; | |
22305
3d1b23cf3d08
Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
voroshil
parents:
22028
diff
changeset
|
314 CopyMediaType(pmt,&(((CInputPin*)This)->type)); |
168 | 315 return 0; |
316 } | |
317 | |
22028 | 318 /** |
319 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
320 * | |
321 * \param[in] This pointer to IPin interface | |
322 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
323 * | |
324 * \return S_OK - success | |
325 * \return E_POINTER - Null pointer | |
326 * | |
327 * \note | |
328 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
329 * | |
330 */ | |
3056 | 331 static long STDCALL CInputPin_QueryPinInfo(IPin* This, |
332 /* [out] */ PIN_INFO *pInfo) | |
168 | 333 { |
1545 | 334 CBaseFilter* lparent=((CInputPin*)This)->parent; |
3056 | 335 Debug printf("CInputPin_QueryPinInfo(%p) called\n", This); |
336 pInfo->dir = PINDIR_OUTPUT; | |
337 pInfo->pFilter = (IBaseFilter*) lparent; | |
1545 | 338 lparent->vt->AddRef((IUnknown*)lparent); |
3056 | 339 pInfo->achName[0] = 0; |
340 return 0; | |
341 } | |
342 | |
22028 | 343 /** |
344 * \brief IPin::QueryDirection (retrieves pin direction) | |
345 * | |
346 * \param[in] This pointer to IPin interface | |
347 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) | |
348 * | |
349 * \return S_OK - success | |
350 * \return E_POINTER - Null pointer | |
351 * | |
352 */ | |
3056 | 353 static long STDCALL CInputPin_QueryDirection(IPin* This, |
354 /* [out] */ PIN_DIRECTION *pPinDir) | |
355 { | |
356 *pPinDir = PINDIR_OUTPUT; | |
357 Debug printf("CInputPin_QueryDirection(%p) called\n", This); | |
168 | 358 return 0; |
359 } | |
360 | |
22028 | 361 /** |
362 * \brief IPin::QueryId (retrieves pin identificator) | |
363 * | |
364 * \param[in] This pointer to IPin interface | |
365 * \param[out] Id adress of variable, that receives string with pin's Id. | |
366 * | |
367 * \return S_OK - success | |
368 * \return E_OUTOFMEMORY - Insufficient memory | |
369 * \return E_POINTER - Null pointer | |
370 * | |
371 * \note | |
372 * Pin's Id is not the same as pin's name | |
373 * | |
374 */ | |
3056 | 375 static long STDCALL CInputPin_QueryId(IPin* This, |
376 /* [out] */ unsigned short* *Id) | |
168 | 377 { |
3056 | 378 Debug unimplemented("CInputPin_QueryId", This); |
379 return E_NOTIMPL; | |
168 | 380 } |
381 | |
22028 | 382 /** |
383 * \brief IPin::QueryAccept (determines can media type be accepted or not) | |
384 * | |
385 * \param[in] This pointer to IPin interface | |
386 * \param[in] pmt Media type to check | |
387 * | |
388 * \return S_OK - success | |
389 * \return S_FALSE - pin rejects media type | |
390 * | |
391 */ | |
3056 | 392 static long STDCALL CInputPin_QueryAccept(IPin* This, |
3130 | 393 /* [in] */ const AM_MEDIA_TYPE* pmt) |
168 | 394 { |
3056 | 395 Debug unimplemented("CInputPin_QueryAccept", This); |
168 | 396 return E_NOTIMPL; |
397 } | |
398 | |
22028 | 399 /** |
400 * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types) | |
401 * | |
402 * \param[in] This pointer to IPin interface | |
403 * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface | |
404 * | |
405 * \return S_OK - success | |
406 * \return E_OUTOFMEMORY - Insufficient memory | |
407 * \return E_POINTER - Null pointer | |
408 * | |
409 * \note | |
410 * Caller must call Release on received interface when done | |
411 * | |
412 */ | |
3056 | 413 static long STDCALL CInputPin_EnumMediaTypes(IPin* This, |
3130 | 414 /* [out] */ IEnumMediaTypes** ppEnum) |
168 | 415 { |
3056 | 416 Debug unimplemented("CInputPin_EnumMediaTypes", This); |
417 return E_NOTIMPL; | |
418 } | |
419 | |
22028 | 420 /** |
421 * \brief IPin::QueryInternalConnections (retries pin's internal connections) | |
422 * | |
423 * \param[in] This pointer to IPin interface | |
424 * \param[out] apPin Array that receives pins, internally connected to this | |
425 * \param[in,out] nPint Size of an array | |
426 * | |
427 * \return S_OK - success | |
428 * \return S_FALSE - pin rejects media type | |
429 * \return E_NOTIMPL - not implemented | |
430 * | |
431 */ | |
3056 | 432 static long STDCALL CInputPin_QueryInternalConnections(IPin* This, |
3130 | 433 /* [out] */ IPin** apPin, |
3056 | 434 /* [out][in] */ unsigned long *nPin) |
435 { | |
436 Debug unimplemented("CInputPin_QueryInternalConnections", This); | |
437 return E_NOTIMPL; | |
438 } | |
439 | |
22028 | 440 /** |
441 * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command) | |
442 * | |
443 * \param[in] This pointer to IPin interface | |
444 * | |
445 * \return S_OK - success | |
446 * \return E_UNEXPECTED - The pin is output pin | |
447 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
448 * \note |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
449 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
450 * IMemAllocator::GetBuffer runs in different (streaming) thread then other |
22028 | 451 * methods (application thread). |
452 * IMemoryInputPin::NewSegment runs either in streaming or application thread. | |
453 * Developer must use critical sections for thread-safing work. | |
454 * | |
455 */ | |
3056 | 456 static long STDCALL CInputPin_EndOfStream(IPin * This) |
457 { | |
458 Debug unimplemented("CInputPin_EndOfStream", This); | |
168 | 459 return E_NOTIMPL; |
460 } | |
461 | |
462 | |
22028 | 463 /** |
464 * \brief IPin::BeginFlush (begins a flush operation) | |
465 * | |
466 * \param[in] This pointer to IPin interface | |
467 * | |
468 * \return S_OK - success | |
469 * \return E_UNEXPECTED - The pin is output pin | |
470 * | |
471 */ | |
3056 | 472 static long STDCALL CInputPin_BeginFlush(IPin * This) |
168 | 473 { |
3056 | 474 Debug unimplemented("CInputPin_BeginFlush", This); |
168 | 475 return E_NOTIMPL; |
476 } | |
477 | |
478 | |
22028 | 479 /** |
480 * \brief IPin::EndFlush (ends a flush operation) | |
481 * | |
482 * \param[in] This pointer to IPin interface | |
483 * | |
484 * \return S_OK - success | |
485 * \return E_UNEXPECTED - The pin is output pin | |
486 * | |
487 */ | |
3130 | 488 static long STDCALL CInputPin_EndFlush(IPin* This) |
168 | 489 { |
3056 | 490 Debug unimplemented("CInputPin_EndFlush", This); |
168 | 491 return E_NOTIMPL; |
492 } | |
493 | |
22028 | 494 /** |
495 * \brief IPin::NewSegment (media sample received after this call grouped as segment with common | |
496 * start,stop time and rate) | |
497 * | |
498 * \param[in] This pointer to IPin interface | |
499 * \param[in] tStart start time of new segment | |
500 * \param[in] tStop end time of new segment | |
501 * \param[in] dRate rate at wich segment should be processed | |
502 * | |
503 * \return S_OK - success | |
504 * \return E_UNEXPECTED - The pin is output pin | |
505 * | |
506 */ | |
3130 | 507 static long STDCALL CInputPin_NewSegment(IPin* This, |
3056 | 508 /* [in] */ REFERENCE_TIME tStart, |
509 /* [in] */ REFERENCE_TIME tStop, | |
510 /* [in] */ double dRate) | |
168 | 511 { |
3056 | 512 Debug unimplemented("CInputPin_NewSegment", This); |
168 | 513 return E_NOTIMPL; |
1545 | 514 } |
168 | 515 |
22028 | 516 /** |
517 * \brief CInputPin destructor | |
518 * | |
519 * \param[in] This pointer to CInputPin class | |
520 * | |
521 */ | |
3056 | 522 static void CInputPin_Destroy(CInputPin* This) |
168 | 523 { |
3056 | 524 free(This->vt); |
22305
3d1b23cf3d08
Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
voroshil
parents:
22028
diff
changeset
|
525 FreeMediaType(&(This->type)); |
3056 | 526 free(This); |
1545 | 527 } |
528 | |
3056 | 529 IMPLEMENT_IUNKNOWN(CInputPin) |
530 | |
22028 | 531 /** |
532 * \brief CInputPin constructor | |
533 * | |
534 * \param[in] amt media type for pin | |
535 * | |
536 * \return pointer to CInputPin if success | |
537 * \return NULL if error occured | |
538 * | |
539 */ | |
3056 | 540 CInputPin* CInputPinCreate(CBaseFilter* p, const AM_MEDIA_TYPE* amt) |
168 | 541 { |
30702 | 542 CInputPin* This = malloc(sizeof(CInputPin)); |
3056 | 543 |
3467 | 544 if (!This) |
545 return NULL; | |
546 | |
547 This->refcount = 1; | |
3056 | 548 This->parent = p; |
22305
3d1b23cf3d08
Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
voroshil
parents:
22028
diff
changeset
|
549 CopyMediaType(&(This->type),amt); |
3056 | 550 |
30702 | 551 This->vt= malloc(sizeof(IPin_vt)); |
3467 | 552 |
553 if (!This->vt) | |
554 { | |
555 free(This); | |
556 return NULL; | |
557 } | |
558 | |
3056 | 559 This->vt->QueryInterface = CInputPin_QueryInterface; |
560 This->vt->AddRef = CInputPin_AddRef; | |
561 This->vt->Release = CInputPin_Release; | |
562 This->vt->Connect = CInputPin_Connect; | |
563 This->vt->ReceiveConnection = CInputPin_ReceiveConnection; | |
564 This->vt->Disconnect = CInputPin_Disconnect; | |
565 This->vt->ConnectedTo = CInputPin_ConnectedTo; | |
566 This->vt->ConnectionMediaType = CInputPin_ConnectionMediaType; | |
567 This->vt->QueryPinInfo = CInputPin_QueryPinInfo; | |
568 This->vt->QueryDirection = CInputPin_QueryDirection; | |
569 This->vt->QueryId = CInputPin_QueryId; | |
570 This->vt->QueryAccept = CInputPin_QueryAccept; | |
571 This->vt->EnumMediaTypes = CInputPin_EnumMediaTypes; | |
572 This->vt->QueryInternalConnections = CInputPin_QueryInternalConnections; | |
573 This->vt->EndOfStream = CInputPin_EndOfStream; | |
574 This->vt->BeginFlush = CInputPin_BeginFlush; | |
575 This->vt->EndFlush = CInputPin_EndFlush; | |
576 This->vt->NewSegment = CInputPin_NewSegment; | |
577 | |
578 This->interfaces[0]=IID_IUnknown; | |
579 | |
580 return This; | |
1545 | 581 } |
168 | 582 |
3056 | 583 |
584 /************* | |
585 * BaseFilter | |
586 *************/ | |
587 | |
588 static long STDCALL CBaseFilter_GetClassID(IBaseFilter * This, | |
589 /* [out] */ CLSID *pClassID) | |
168 | 590 { |
3056 | 591 Debug unimplemented("CBaseFilter_GetClassID", This); |
168 | 592 return E_NOTIMPL; |
1545 | 593 } |
168 | 594 |
22028 | 595 /** |
596 * \brief IMediaFilter::Stop (stops the filter) | |
597 * | |
598 * \param[in] This pointer to IBaseFilter interface | |
599 * | |
600 * \return S_OK success | |
601 * \return S_FALSE transition is not complete | |
602 * | |
603 * \remarks | |
604 * When filter is stopped it does onot deliver or process any samples and rejects any samples | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
605 * from upstream filter. |
22028 | 606 * Transition may be asynchronous. In this case method should return S_FALSE. |
607 * Method always sets filter's state to State_Stopped even if error occured. | |
608 * | |
609 */ | |
3056 | 610 static long STDCALL CBaseFilter_Stop(IBaseFilter* This) |
168 | 611 { |
3056 | 612 Debug unimplemented("CBaseFilter_Stop", This); |
168 | 613 return E_NOTIMPL; |
1545 | 614 } |
168 | 615 |
22028 | 616 /** |
617 * \brief IMediaFilter::Pause (pauses filter) | |
618 * | |
619 * \param[in] This pointer to IBaseFilter interface | |
620 * | |
621 * \return S_OK success | |
622 * \return S_FALSE transition is not complete | |
623 * | |
624 * \remarks | |
625 * When filter is paused it can receive, process and deliver samples. | |
626 * Live source filters do not deliver any samples while paused. | |
627 * Transition may be asynchronous. In this case method should return S_FALSE. | |
628 * Method always sets filter's state to State_Stopped even if error occured. | |
629 * | |
630 */ | |
3056 | 631 static long STDCALL CBaseFilter_Pause(IBaseFilter* This) |
168 | 632 { |
3056 | 633 Debug unimplemented("CBaseFilter_Pause", This); |
634 return E_NOTIMPL; | |
635 } | |
636 | |
22028 | 637 /** |
638 * \brief IMediaFilter::Run (runs the filter) | |
639 * | |
640 * \param[in] This pointer to IBaseFilter interface | |
641 * \param[in] tStart Reference time corresponding to stream time 0. | |
642 * | |
643 * \return S_OK success | |
644 * \return S_FALSE transition is not complete | |
645 * | |
646 * \remarks | |
647 * When filter is running it can receive, process and deliver samples. Source filters | |
648 * generatesnew samples, and renderers renders them. | |
649 * Stream time is calculated as the current reference time minus tStart. | |
650 * Graph Manager sets tStart slightly in the future according to graph latency. | |
651 * | |
652 */ | |
3056 | 653 static long STDCALL CBaseFilter_Run(IBaseFilter* This, REFERENCE_TIME tStart) |
654 { | |
655 Debug unimplemented("CBaseFilter_Run", This); | |
168 | 656 return E_NOTIMPL; |
1545 | 657 } |
168 | 658 |
22028 | 659 /** |
660 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused)) | |
661 * | |
662 * \param[in] This pointer to IBaseFilter interface | |
663 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass | |
664 * INFINITE. | |
665 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration. | |
666 * | |
667 * \return S_OK success | |
668 * \return E_POINTER Null pointer | |
669 * \return VFW_S_STATE_INTERMEDATE Intermediate state | |
670 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data. | |
671 * | |
672 */ | |
3056 | 673 static long STDCALL CBaseFilter_GetState(IBaseFilter* This, |
674 /* [in] */ unsigned long dwMilliSecsTimeout, | |
675 // /* [out] */ FILTER_STATE *State) | |
676 void* State) | |
168 | 677 { |
3056 | 678 Debug unimplemented("CBaseFilter_GetState", This); |
679 return E_NOTIMPL; | |
1545 | 680 } |
168 | 681 |
22028 | 682 /** |
683 * \brief IMediaFilter::SetSyncSource (sets the reference clock) | |
684 * | |
685 * \param[in] This pointer to IBaseFilter interface | |
686 * \param[in] pClock IReferenceClock interface of reference clock | |
687 * | |
688 * \return S_OK success | |
689 * \return apripriate error otherwise | |
690 * | |
691 */ | |
3056 | 692 static long STDCALL CBaseFilter_SetSyncSource(IBaseFilter* This, |
693 /* [in] */ IReferenceClock *pClock) | |
694 { | |
695 Debug unimplemented("CBaseFilter_SetSyncSource", This); | |
696 return E_NOTIMPL; | |
697 } | |
1545 | 698 |
22028 | 699 /** |
700 * \brief IMediafilter::GetSyncSource (gets current reference clock) | |
701 * | |
702 * \param[in] This pointer to IBaseFilter interface | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
703 * \param[out] pClock address of variable that receives pointer to clock's |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
704 * IReferenceClock interface |
22028 | 705 * |
706 * \return S_OK success | |
707 * \return E_POINTER Null pointer | |
708 * | |
709 */ | |
3056 | 710 static long STDCALL CBaseFilter_GetSyncSource(IBaseFilter* This, |
711 /* [out] */ IReferenceClock **pClock) | |
168 | 712 { |
3056 | 713 Debug unimplemented("CBaseFilter_GetSyncSource", This); |
168 | 714 return E_NOTIMPL; |
1545 | 715 } |
168 | 716 |
1545 | 717 |
22028 | 718 /** |
719 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter) | |
720 * | |
721 * \param[in] This pointer to IBaseFilter interface | |
722 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface | |
723 * | |
724 * \return S_OK success | |
725 * \return E_OUTOFMEMORY Insufficient memory | |
726 * \return E_POINTER Null pointer | |
727 * | |
728 */ | |
3056 | 729 static long STDCALL CBaseFilter_EnumPins(IBaseFilter* This, |
730 /* [out] */ IEnumPins **ppEnum) | |
731 { | |
732 Debug printf("CBaseFilter_EnumPins(%p) called\n", This); | |
733 *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter*)This)->pin, ((CBaseFilter*)This)->unused_pin); | |
734 return 0; | |
735 } | |
736 | |
22028 | 737 /** |
738 * \brief IBaseFilter::FindPin (retrieves the pin with specified id) | |
739 * | |
740 * \param[in] This pointer to IBaseFilter interface | |
741 * \param[in] Id constant wide string, containing pin id | |
742 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface | |
743 * | |
744 * \return S_OK success | |
745 * \return E_POINTER Null pointer | |
746 * \return VFW_E_NOT_FOUND Could not find a pin with specified id | |
747 * | |
748 * \note | |
749 * Be sure to release the interface after use. | |
750 * | |
751 */ | |
3056 | 752 static long STDCALL CBaseFilter_FindPin(IBaseFilter* This, |
753 /* [string][in] */ const unsigned short* Id, | |
754 /* [out] */ IPin **ppPin) | |
168 | 755 { |
3056 | 756 Debug unimplemented("CBaseFilter_FindPin\n", This); |
757 return E_NOTIMPL; | |
758 } | |
759 | |
22028 | 760 /** |
761 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter) | |
762 * | |
763 * \param[in] This pointer to IBaseFilter interface | |
764 * \param[out] pInfo pointer to FILTER_INFO structure | |
765 * | |
766 * \return S_OK success | |
767 * \return E_POINTER Null pointer | |
768 * | |
769 * \note | |
770 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use. | |
771 * | |
772 */ | |
3130 | 773 static long STDCALL CBaseFilter_QueryFilterInfo(IBaseFilter* This, |
3056 | 774 // /* [out] */ FILTER_INFO *pInfo) |
775 void* pInfo) | |
776 { | |
777 Debug unimplemented("CBaseFilter_QueryFilterInfo", This); | |
778 return E_NOTIMPL; | |
779 } | |
780 | |
22028 | 781 /** |
782 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph) | |
783 * | |
784 * \param[in] This pointer to IBaseFilter interface | |
785 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph | |
786 * \param[in] pName pointer to wide character string that specifies a name for the filter | |
787 * | |
788 * \return S_OK success | |
789 * \return apropriate error code otherwise | |
790 * | |
791 * \remarks | |
792 * Filter should not call to graph's AddRef method. | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
793 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with |
22028 | 794 * the value NULL. |
795 * | |
796 */ | |
3130 | 797 static long STDCALL CBaseFilter_JoinFilterGraph(IBaseFilter* This, |
798 /* [in] */ IFilterGraph* pGraph, | |
3056 | 799 /* [string][in] */ const unsigned short* pName) |
800 { | |
801 Debug unimplemented("CBaseFilter_JoinFilterGraph", This); | |
802 return E_NOTIMPL; | |
803 } | |
804 | |
22028 | 805 /** |
806 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info) | |
807 * | |
808 * \param[in] This pointer to IBaseFilter interface | |
809 * \param[out] address of variable that receives pointer to a string containing vendor info | |
810 * | |
811 * \return S_OK success | |
812 * \return E_POINTER Null pointer | |
813 * \return E_NOTIMPL Not implemented | |
814 * | |
815 * \remarks | |
816 * Call to CoTaskMemFree to free memory allocated for string | |
817 * | |
818 */ | |
3130 | 819 static long STDCALL CBaseFilter_QueryVendorInfo(IBaseFilter* This, |
820 /* [string][out] */ unsigned short** pVendorInfo) | |
3056 | 821 { |
822 Debug unimplemented("CBaseFilter_QueryVendorInfo", This); | |
168 | 823 return E_NOTIMPL; |
1545 | 824 } |
168 | 825 |
22028 | 826 /** |
827 * \brief CBaseFilter::GetPin (gets used pin) | |
828 * | |
829 * \param[in] This pointer to CBaseFilter object | |
830 * | |
831 * \return pointer to used pin's IPin interface | |
832 * | |
833 */ | |
3056 | 834 static IPin* CBaseFilter_GetPin(CBaseFilter* This) |
835 { | |
836 return This->pin; | |
837 } | |
1545 | 838 |
22028 | 839 /** |
840 * \brief CBaseFilter::GetUnusedPin (gets used pin) | |
841 * | |
842 * \param[in] This pointer to CBaseFilter object | |
843 * | |
844 * \return pointer to unused pin's IPin interface | |
845 * | |
846 */ | |
3056 | 847 static IPin* CBaseFilter_GetUnusedPin(CBaseFilter* This) |
168 | 848 { |
3056 | 849 return This->unused_pin; |
850 } | |
851 | |
22028 | 852 /** |
853 * \brief CBaseFilter destructor | |
854 * | |
855 * \param[in] This pointer to CBaseFilter object | |
856 * | |
857 */ | |
3056 | 858 static void CBaseFilter_Destroy(CBaseFilter* This) |
859 { | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30702
diff
changeset
|
860 free(This->vt); |
3467 | 861 if (This->pin) |
862 This->pin->vt->Release((IUnknown*)This->pin); | |
863 if (This->unused_pin) | |
864 This->unused_pin->vt->Release((IUnknown*)This->unused_pin); | |
3056 | 865 free(This); |
1545 | 866 } |
168 | 867 |
3056 | 868 IMPLEMENT_IUNKNOWN(CBaseFilter) |
1545 | 869 |
22028 | 870 /** |
871 * \brief CBaseFilter constructor | |
872 * | |
873 * \param[in] type Pointer to media type for connection | |
874 * \param[in] parent Pointer to parent CBaseFilter2 object | |
875 * | |
876 * \return pointer to CBaseFilter object or NULL if error occured | |
877 * | |
878 */ | |
3056 | 879 CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* type, CBaseFilter2* parent) |
168 | 880 { |
30702 | 881 CBaseFilter* This = malloc(sizeof(CBaseFilter)); |
3467 | 882 if (!This) |
883 return NULL; | |
884 | |
3056 | 885 This->refcount = 1; |
886 | |
887 This->pin = (IPin*) CInputPinCreate(This, type); | |
888 This->unused_pin = (IPin*) CRemotePinCreate(This, parent->GetPin(parent)); | |
889 | |
30702 | 890 This->vt = malloc(sizeof(IBaseFilter_vt)); |
3467 | 891 if (!This->vt || !This->pin || !This->unused_pin) |
892 { | |
893 CBaseFilter_Destroy(This); | |
894 return NULL; | |
895 } | |
896 | |
3056 | 897 This->vt->QueryInterface = CBaseFilter_QueryInterface; |
898 This->vt->AddRef = CBaseFilter_AddRef; | |
899 This->vt->Release = CBaseFilter_Release; | |
900 This->vt->GetClassID = CBaseFilter_GetClassID; | |
901 This->vt->Stop = CBaseFilter_Stop; | |
902 This->vt->Pause = CBaseFilter_Pause; | |
903 This->vt->Run = CBaseFilter_Run; | |
904 This->vt->GetState = CBaseFilter_GetState; | |
905 This->vt->SetSyncSource = CBaseFilter_SetSyncSource; | |
906 This->vt->GetSyncSource = CBaseFilter_GetSyncSource; | |
907 This->vt->EnumPins = CBaseFilter_EnumPins; | |
908 This->vt->FindPin = CBaseFilter_FindPin; | |
909 This->vt->QueryFilterInfo = CBaseFilter_QueryFilterInfo; | |
910 This->vt->JoinFilterGraph = CBaseFilter_JoinFilterGraph; | |
911 This->vt->QueryVendorInfo = CBaseFilter_QueryVendorInfo; | |
912 | |
913 This->interfaces[0] = IID_IUnknown; | |
914 This->interfaces[1] = IID_IBaseFilter; | |
915 | |
916 This->GetPin = CBaseFilter_GetPin; | |
917 This->GetUnusedPin = CBaseFilter_GetUnusedPin; | |
918 | |
919 return This; | |
1545 | 920 } |
168 | 921 |
922 | |
3056 | 923 /************** |
924 * BaseFilter2 | |
925 **************/ | |
168 | 926 |
927 | |
3130 | 928 static long STDCALL CBaseFilter2_GetClassID(IBaseFilter* This, |
929 /* [out] */ CLSID* pClassID) | |
168 | 930 { |
3056 | 931 Debug unimplemented("CBaseFilter2_GetClassID", This); |
168 | 932 return E_NOTIMPL; |
1545 | 933 } |
168 | 934 |
22028 | 935 /** |
936 * \brief IMediaFilter::Stop (stops the filter) | |
937 * | |
938 * \param[in] This pointer to IBaseFilter interface | |
939 * | |
940 * \return S_OK success | |
941 * \return S_FALSE transition is not complete | |
942 * | |
943 * \remarks | |
944 * When filter is stopped it does onot deliver or process any samples and rejects any samples | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
945 * from upstream filter. |
22028 | 946 * Transition may be asynchronous. In this case method should return S_FALSE. |
947 * Method always sets filter's state to State_Stopped even if error occured. | |
948 * | |
949 */ | |
3130 | 950 static long STDCALL CBaseFilter2_Stop(IBaseFilter* This) |
168 | 951 { |
3056 | 952 Debug unimplemented("CBaseFilter2_Stop", This); |
168 | 953 return E_NOTIMPL; |
1545 | 954 } |
168 | 955 |
22028 | 956 /** |
957 * \brief IMediaFilter::Pause (pauses filter) | |
958 * | |
959 * \param[in] This pointer to IBaseFilter interface | |
960 * | |
961 * \return S_OK success | |
962 * \return S_FALSE transition is not complete | |
963 * | |
964 * \remarks | |
965 * When filter is paused it can receive, process and deliver samples. | |
966 * Live source filters do not deliver any samples while paused. | |
967 * Transition may be asynchronous. In this case method should return S_FALSE. | |
968 * Method always sets filter's state to State_Stopped even if error occured. | |
969 * | |
970 */ | |
3130 | 971 static long STDCALL CBaseFilter2_Pause(IBaseFilter* This) |
168 | 972 { |
3056 | 973 Debug unimplemented("CBaseFilter2_Pause", This); |
168 | 974 return E_NOTIMPL; |
1545 | 975 } |
976 | |
22028 | 977 /** |
978 * \brief IMediaFilter::Run (runs the filter) | |
979 * | |
980 * \param[in] This pointer to IBaseFilter interface | |
981 * \param[in] tStart Reference time corresponding to stream time 0. | |
982 * | |
983 * \return S_OK success | |
984 * \return S_FALSE transition is not complete | |
985 * | |
986 * \remarks | |
987 * When filter is running it can receive, process and deliver samples. Source filters | |
988 * generatesnew samples, and renderers renders them. | |
989 * Stream time is calculated as the current reference time minus tStart. | |
990 * Graph Manager sets tStart slightly in the future according to graph latency. | |
991 * | |
992 */ | |
3130 | 993 static long STDCALL CBaseFilter2_Run(IBaseFilter* This, REFERENCE_TIME tStart) |
168 | 994 { |
3056 | 995 Debug unimplemented("CBaseFilter2_Run", This); |
168 | 996 return E_NOTIMPL; |
1545 | 997 } |
168 | 998 |
1545 | 999 |
22028 | 1000 /** |
1001 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused)) | |
1002 * | |
1003 * \param[in] This pointer to IBaseFilter interface | |
1004 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass | |
1005 * INFINITE. | |
1006 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration. | |
1007 * | |
1008 * \return S_OK success | |
1009 * \return E_POINTER Null pointer | |
1010 * \return VFW_S_STATE_INTERMEDATE Intermediate state | |
1011 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data. | |
1012 * | |
1013 */ | |
3056 | 1014 static long STDCALL CBaseFilter2_GetState(IBaseFilter* This, |
1015 /* [in] */ unsigned long dwMilliSecsTimeout, | |
1016 // /* [out] */ FILTER_STATE *State) | |
1017 void* State) | |
1018 { | |
1019 Debug unimplemented("CBaseFilter2_GetState", This); | |
1020 return E_NOTIMPL; | |
1021 } | |
1022 | |
22028 | 1023 /** |
1024 * \brief IMediaFilter::SetSyncSource (sets the reference clock) | |
1025 * | |
1026 * \param[in] This pointer to IBaseFilter interface | |
1027 * \param[in] pClock IReferenceClock interface of reference clock | |
1028 * | |
1029 * \return S_OK success | |
1030 * \return apripriate error otherwise | |
1031 * | |
1032 */ | |
3056 | 1033 static long STDCALL CBaseFilter2_SetSyncSource(IBaseFilter* This, |
1034 /* [in] */ IReferenceClock* pClock) | |
1035 { | |
1036 Debug unimplemented("CBaseFilter2_SetSyncSource", This); | |
1037 return E_NOTIMPL; | |
1038 } | |
1039 | |
22028 | 1040 /** |
1041 * \brief IMediafilter::GetSyncSource (gets current reference clock) | |
1042 * | |
1043 * \param[in] This pointer to IBaseFilter interface | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
1044 * \param[out] pClock address of variable that receives pointer to clock's |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
1045 * IReferenceClock interface |
22028 | 1046 * |
1047 * \return S_OK success | |
1048 * \return E_POINTER Null pointer | |
1049 * | |
1050 */ | |
3056 | 1051 static long STDCALL CBaseFilter2_GetSyncSource(IBaseFilter* This, |
1052 /* [out] */ IReferenceClock** pClock) | |
1053 { | |
1054 Debug unimplemented("CBaseFilter2_GetSyncSource", This); | |
1055 return E_NOTIMPL; | |
1056 } | |
1057 | |
22028 | 1058 /** |
1059 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter) | |
1060 * | |
1061 * \param[in] This pointer to IBaseFilter interface | |
1062 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface | |
1063 * | |
1064 * \return S_OK success | |
1065 * \return E_OUTOFMEMORY Insufficient memory | |
1066 * \return E_POINTER Null pointer | |
1067 * | |
1068 */ | |
3056 | 1069 static long STDCALL CBaseFilter2_EnumPins(IBaseFilter* This, |
1070 /* [out] */ IEnumPins** ppEnum) | |
168 | 1071 { |
3056 | 1072 Debug printf("CBaseFilter2_EnumPins(%p) called\n", This); |
1073 *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter2*)This)->pin, 0); | |
1074 return 0; | |
1075 } | |
1076 | |
22028 | 1077 /** |
1078 * \brief IBaseFilter::FindPin (retrieves the pin with specified id) | |
1079 * | |
1080 * \param[in] This pointer to IBaseFilter interface | |
1081 * \param[in] Id constant wide string, containing pin id | |
1082 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface | |
1083 * | |
1084 * \return S_OK success | |
1085 * \return E_POINTER Null pointer | |
1086 * \return VFW_E_NOT_FOUND Could not find a pin with specified id | |
1087 * | |
1088 * \note | |
1089 * Be sure to release the interface after use. | |
1090 * | |
1091 */ | |
3056 | 1092 static long STDCALL CBaseFilter2_FindPin(IBaseFilter* This, |
1093 /* [string][in] */ const unsigned short* Id, | |
1094 /* [out] */ IPin** ppPin) | |
1095 { | |
1096 Debug unimplemented("CBaseFilter2_FindPin", This); | |
1097 return E_NOTIMPL; | |
1098 } | |
1099 | |
22028 | 1100 /** |
1101 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter) | |
1102 * | |
1103 * \param[in] This pointer to IBaseFilter interface | |
1104 * \param[out] pInfo pointer to FILTER_INFO structure | |
1105 * | |
1106 * \return S_OK success | |
1107 * \return E_POINTER Null pointer | |
1108 * | |
1109 * \note | |
1110 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use. | |
1111 * | |
1112 */ | |
3056 | 1113 static long STDCALL CBaseFilter2_QueryFilterInfo(IBaseFilter* This, |
1114 // /* [out] */ FILTER_INFO *pInfo) | |
1115 void* pInfo) | |
1116 { | |
1117 Debug unimplemented("CBaseFilter2_QueryFilterInfo", This); | |
1118 return E_NOTIMPL; | |
1119 } | |
1120 | |
22028 | 1121 /** |
1122 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph) | |
1123 * | |
1124 * \param[in] This pointer to IBaseFilter interface | |
1125 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph | |
1126 * \param[in] pName pointer to wide character string that specifies a name for the filter | |
1127 * | |
1128 * \return S_OK success | |
1129 * \return apropriate error code otherwise | |
1130 * | |
1131 * \remarks | |
1132 * Filter should not call to graph's AddRef method. | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
1133 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with |
22028 | 1134 * the value NULL. |
1135 * | |
1136 */ | |
3056 | 1137 static long STDCALL CBaseFilter2_JoinFilterGraph(IBaseFilter* This, |
1138 /* [in] */ IFilterGraph* pGraph, | |
1139 /* [string][in] */ | |
1140 const unsigned short* pName) | |
1141 { | |
1142 Debug unimplemented("CBaseFilter2_JoinFilterGraph", This); | |
168 | 1143 return E_NOTIMPL; |
1545 | 1144 } |
168 | 1145 |
22028 | 1146 /** |
1147 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info) | |
1148 * | |
1149 * \param[in] This pointer to IBaseFilter interface | |
1150 * \param[out] address of variable that receives pointer to a string containing vendor info | |
1151 * | |
1152 * \return S_OK success | |
1153 * \return E_POINTER Null pointer | |
1154 * \return E_NOTIMPL Not implemented | |
1155 * | |
1156 * \remarks | |
1157 * Call to CoTaskMemFree to free memory allocated for string | |
1158 * | |
1159 */ | |
3056 | 1160 static long STDCALL CBaseFilter2_QueryVendorInfo(IBaseFilter* This, |
1161 /* [string][out] */ | |
1162 unsigned short** pVendorInfo) | |
168 | 1163 { |
3056 | 1164 Debug unimplemented("CBaseFilter2_QueryVendorInfo", This); |
168 | 1165 return E_NOTIMPL; |
1545 | 1166 } |
168 | 1167 |
22028 | 1168 /** |
1169 * \brief CBaseFilter2::GetPin (gets used pin) | |
1170 * | |
1171 * \param[in] This pointer to CBaseFilter2 object | |
1172 * | |
1173 * \return pointer to used pin's IPin interface | |
1174 * | |
1175 */ | |
3056 | 1176 static IPin* CBaseFilter2_GetPin(CBaseFilter2* This) |
1177 { | |
1178 return This->pin; | |
1179 } | |
1545 | 1180 |
22028 | 1181 /** |
1182 * \brief CBaseFilter2 destructor | |
1183 * | |
1184 * \param[in] This pointer to CBaseFilter2 object | |
1185 * | |
1186 */ | |
3056 | 1187 static void CBaseFilter2_Destroy(CBaseFilter2* This) |
168 | 1188 { |
3130 | 1189 Debug printf("CBaseFilter2_Destroy(%p) called\n", This); |
3467 | 1190 if (This->pin) |
1191 This->pin->vt->Release((IUnknown*) This->pin); | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30702
diff
changeset
|
1192 free(This->vt); |
3056 | 1193 free(This); |
1545 | 1194 } |
168 | 1195 |
3056 | 1196 IMPLEMENT_IUNKNOWN(CBaseFilter2) |
1545 | 1197 |
3056 | 1198 static GUID CBaseFilter2_interf1 = |
1199 {0x76c61a30, 0xebe1, 0x11cf, {0x89, 0xf9, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb}}; | |
22028 | 1200 /// IID_IAMNetShowPreroll |
3056 | 1201 static GUID CBaseFilter2_interf2 = |
1202 {0xaae7e4e2, 0x6388, 0x11d1, {0x8d, 0x93, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2}}; | |
22028 | 1203 /// IID_IAMRebuild |
3056 | 1204 static GUID CBaseFilter2_interf3 = |
1205 {0x02ef04dd, 0x7580, 0x11d1, {0xbe, 0xce, 0x00, 0xc0, 0x4f, 0xb6, 0xe9, 0x37}}; | |
1206 | |
22028 | 1207 /** |
1208 * \brief CBaseFilter2 constructor | |
1209 * | |
1210 * \return pointer to CBaseFilter2 object or NULL if error occured | |
1211 * | |
1212 */ | |
3056 | 1213 CBaseFilter2* CBaseFilter2Create() |
168 | 1214 { |
30702 | 1215 CBaseFilter2* This = malloc(sizeof(CBaseFilter2)); |
3056 | 1216 |
3467 | 1217 if (!This) |
1218 return NULL; | |
1219 | |
3056 | 1220 This->refcount = 1; |
1221 This->pin = (IPin*) CRemotePin2Create(This); | |
1222 | |
30702 | 1223 This->vt = malloc(sizeof(IBaseFilter_vt)); |
3467 | 1224 |
1225 if (!This->pin || !This->vt) | |
1226 { | |
1227 CBaseFilter2_Destroy(This); | |
1228 return NULL; | |
1229 } | |
1230 | |
3056 | 1231 memset(This->vt, 0, sizeof(IBaseFilter_vt)); |
1232 This->vt->QueryInterface = CBaseFilter2_QueryInterface; | |
1233 This->vt->AddRef = CBaseFilter2_AddRef; | |
1234 This->vt->Release = CBaseFilter2_Release; | |
1235 This->vt->GetClassID = CBaseFilter2_GetClassID; | |
1236 This->vt->Stop = CBaseFilter2_Stop; | |
1237 This->vt->Pause = CBaseFilter2_Pause; | |
1238 This->vt->Run = CBaseFilter2_Run; | |
1239 This->vt->GetState = CBaseFilter2_GetState; | |
1240 This->vt->SetSyncSource = CBaseFilter2_SetSyncSource; | |
1241 This->vt->GetSyncSource = CBaseFilter2_GetSyncSource; | |
1242 This->vt->EnumPins = CBaseFilter2_EnumPins; | |
1243 This->vt->FindPin = CBaseFilter2_FindPin; | |
1244 This->vt->QueryFilterInfo = CBaseFilter2_QueryFilterInfo; | |
1245 This->vt->JoinFilterGraph = CBaseFilter2_JoinFilterGraph; | |
1246 This->vt->QueryVendorInfo = CBaseFilter2_QueryVendorInfo; | |
1247 | |
1248 This->GetPin = CBaseFilter2_GetPin; | |
1249 | |
1250 This->interfaces[0] = IID_IUnknown; | |
1251 This->interfaces[1] = IID_IBaseFilter; | |
1252 This->interfaces[2] = CBaseFilter2_interf1; | |
1253 This->interfaces[3] = CBaseFilter2_interf2; | |
1254 This->interfaces[4] = CBaseFilter2_interf3; | |
1255 | |
1256 return This; | |
1545 | 1257 } |
168 | 1258 |
1545 | 1259 |
3056 | 1260 /************* |
1261 * CRemotePin | |
1262 *************/ | |
1545 | 1263 |
168 | 1264 |
22028 | 1265 /** |
1266 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist) | |
1267 * | |
1268 * \param[in] This pointer to IPin interface | |
1269 * \param[out] pPin pointer to remote pin's IPin interface | |
1270 * | |
1271 * \return S_OK - success | |
1272 * \return E_POINTER - Null pointer | |
1273 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
1274 * | |
1275 * \note | |
1276 * Caller must call Release on received IPin, when done | |
1277 */ | |
3056 | 1278 static long STDCALL CRemotePin_ConnectedTo(IPin* This, /* [out] */ IPin** pPin) |
168 | 1279 { |
3056 | 1280 Debug printf("CRemotePin_ConnectedTo(%p) called\n", This); |
1545 | 1281 if (!pPin) |
1282 return E_INVALIDARG; | |
3056 | 1283 *pPin = ((CRemotePin*)This)->remote_pin; |
1545 | 1284 (*pPin)->vt->AddRef((IUnknown*)(*pPin)); |
1285 return 0; | |
1286 } | |
168 | 1287 |
22028 | 1288 /** |
1289 * \brief IPin::QueryDirection (retrieves pin direction) | |
1290 * | |
1291 * \param[in] This pointer to IPin interface | |
1292 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) | |
1293 * | |
1294 * \return S_OK - success | |
1295 * \return E_POINTER - Null pointer | |
1296 * | |
1297 */ | |
3056 | 1298 static long STDCALL CRemotePin_QueryDirection(IPin* This, |
3130 | 1299 /* [out] */ PIN_DIRECTION* pPinDir) |
1545 | 1300 { |
3056 | 1301 Debug printf("CRemotePin_QueryDirection(%p) called\n", This); |
1545 | 1302 if (!pPinDir) |
1303 return E_INVALIDARG; | |
1304 *pPinDir=PINDIR_INPUT; | |
1305 return 0; | |
1306 } | |
1307 | |
22028 | 1308 /** |
1309 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist) | |
1310 * | |
1311 * \param[in] This pointer to IPin interface | |
1312 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type | |
1313 * | |
1314 * \return S_OK - success | |
1315 * \return E_POINTER - Null pointer | |
1316 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
1317 * | |
1318 */ | |
1545 | 1319 static long STDCALL CRemotePin_ConnectionMediaType(IPin* This, /* [out] */ AM_MEDIA_TYPE* pmt) |
168 | 1320 { |
3056 | 1321 Debug unimplemented("CRemotePin_ConnectionMediaType", This); |
168 | 1322 return E_NOTIMPL; |
1323 } | |
1324 | |
22028 | 1325 /** |
1326 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
1327 * | |
1328 * \param[in] This pointer to IPin interface | |
1329 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
1330 * | |
1331 * \return S_OK - success | |
1332 * \return E_POINTER - Null pointer | |
1333 * | |
1334 * \note | |
1335 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
1336 * | |
1337 */ | |
1545 | 1338 static long STDCALL CRemotePin_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO* pInfo) |
168 | 1339 { |
1545 | 1340 CBaseFilter* lparent = ((CRemotePin*)This)->parent; |
3056 | 1341 Debug printf("CRemotePin_QueryPinInfo(%p) called\n", This); |
1342 pInfo->dir= PINDIR_INPUT; | |
1343 pInfo->pFilter = (IBaseFilter*) lparent; | |
1545 | 1344 lparent->vt->AddRef((IUnknown*)lparent); |
1345 pInfo->achName[0]=0; | |
1346 return 0; | |
1347 } | |
1348 | |
22028 | 1349 /** |
1350 * \brief CRemotePin destructor | |
1351 * | |
1352 * \param[in] This pointer to CRemotePin object | |
1353 * | |
1354 */ | |
3056 | 1355 static void CRemotePin_Destroy(CRemotePin* This) |
1356 { | |
1357 Debug printf("CRemotePin_Destroy(%p) called\n", This); | |
1358 free(This->vt); | |
1359 free(This); | |
1360 } | |
1361 | |
1362 IMPLEMENT_IUNKNOWN(CRemotePin) | |
1363 | |
22028 | 1364 /** |
1365 * \brief CRemotePin constructor | |
1366 * | |
1367 * \param[in] pt parent filter | |
1368 * \param[in] rpin remote pin | |
1369 * | |
1370 * \return pointer to CRemotePin or NULL if error occured | |
1371 * | |
1372 */ | |
3056 | 1373 CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin) |
1374 { | |
30702 | 1375 CRemotePin* This = malloc(sizeof(CRemotePin)); |
3467 | 1376 |
1377 if (!This) | |
1378 return NULL; | |
1379 | |
3056 | 1380 Debug printf("CRemotePinCreate() called -> %p\n", This); |
1381 | |
1382 This->parent = pt; | |
1383 This->remote_pin = rpin; | |
1384 This->refcount = 1; | |
1385 | |
30702 | 1386 This->vt = malloc(sizeof(IPin_vt)); |
3467 | 1387 |
1388 if (!This->vt) | |
1389 { | |
1390 free(This); | |
1391 return NULL; | |
1392 } | |
1393 | |
3056 | 1394 memset(This->vt, 0, sizeof(IPin_vt)); |
1395 This->vt->QueryInterface = CRemotePin_QueryInterface; | |
1396 This->vt->AddRef = CRemotePin_AddRef; | |
1397 This->vt->Release = CRemotePin_Release; | |
1398 This->vt->QueryDirection = CRemotePin_QueryDirection; | |
1399 This->vt->ConnectedTo = CRemotePin_ConnectedTo; | |
1400 This->vt->ConnectionMediaType = CRemotePin_ConnectionMediaType; | |
1401 This->vt->QueryPinInfo = CRemotePin_QueryPinInfo; | |
1402 | |
1403 This->interfaces[0] = IID_IUnknown; | |
1404 | |
1405 return This; | |
1406 } | |
1407 | |
1408 | |
1409 /************* | |
3130 | 1410 * CRemotePin2 |
3056 | 1411 *************/ |
1412 | |
1545 | 1413 |
22028 | 1414 /** |
1415 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
1416 * | |
1417 * \param[in] This pointer to IPin interface | |
1418 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
1419 * | |
1420 * \return S_OK - success | |
1421 * \return E_POINTER - Null pointer | |
1422 * | |
1423 * \note | |
1424 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
1425 * | |
1426 */ | |
3130 | 1427 static long STDCALL CRemotePin2_QueryPinInfo(IPin* This, |
1428 /* [out] */ PIN_INFO* pInfo) | |
1545 | 1429 { |
1430 CBaseFilter2* lparent=((CRemotePin2*)This)->parent; | |
3056 | 1431 Debug printf("CRemotePin2_QueryPinInfo(%p) called\n", This); |
1545 | 1432 pInfo->pFilter=(IBaseFilter*)lparent; |
1433 lparent->vt->AddRef((IUnknown*)lparent); | |
1434 pInfo->dir=PINDIR_OUTPUT; | |
168 | 1435 pInfo->achName[0]=0; |
1436 return 0; | |
1437 } | |
1545 | 1438 |
22028 | 1439 /** |
1440 * \brief CremotePin2 destructor | |
1441 * | |
1442 * \param This pointer to CRemotePin2 object | |
1443 * | |
1444 * FIXME - not being released! | |
1445 */ | |
3056 | 1446 static void CRemotePin2_Destroy(CRemotePin2* This) |
1545 | 1447 { |
3056 | 1448 Debug printf("CRemotePin2_Destroy(%p) called\n", This); |
1449 free(This->vt); | |
1450 free(This); | |
1545 | 1451 } |
1452 | |
3056 | 1453 IMPLEMENT_IUNKNOWN(CRemotePin2) |
1454 | |
22028 | 1455 /** |
1456 * \brief CRemotePin2 contructor | |
1457 * | |
1458 * \param[in] p pointer to parent CBaseFilter2 object | |
1459 * | |
1460 * \return pointer to CRemotePin2 object or NULL if error occured | |
1461 * | |
1462 */ | |
3056 | 1463 CRemotePin2* CRemotePin2Create(CBaseFilter2* p) |
1545 | 1464 { |
30702 | 1465 CRemotePin2* This = malloc(sizeof(CRemotePin2)); |
3467 | 1466 |
1467 if (!This) | |
1468 return NULL; | |
1469 | |
3056 | 1470 Debug printf("CRemotePin2Create() called -> %p\n", This); |
1471 | |
1472 This->parent = p; | |
1473 This->refcount = 1; | |
1474 | |
30702 | 1475 This->vt = malloc(sizeof(IPin_vt)); |
3467 | 1476 |
1477 if (!This->vt) | |
1478 { | |
1479 free(This); | |
1480 return NULL; | |
1481 } | |
1482 | |
3056 | 1483 memset(This->vt, 0, sizeof(IPin_vt)); |
1484 This->vt->QueryInterface = CRemotePin2_QueryInterface; | |
1485 This->vt->AddRef = CRemotePin2_AddRef; | |
1486 This->vt->Release = CRemotePin2_Release; | |
1487 This->vt->QueryPinInfo = CRemotePin2_QueryPinInfo; | |
1488 | |
1489 This->interfaces[0] = IID_IUnknown; | |
1490 | |
1491 return This; | |
1545 | 1492 } |