Mercurial > mplayer.hg
comparison loader/dshow/outputpin.c @ 22014:9472dc33de99
Cosmetics. Doxygen comments.
author | voroshil |
---|---|
date | Sat, 27 Jan 2007 15:49:53 +0000 |
parents | 3bf0d70b4c7f |
children | 857cc6beb662 |
comparison
equal
deleted
inserted
replaced
22013:3e00896b3f2b | 22014:9472dc33de99 |
---|---|
9 #include "outputpin.h" | 9 #include "outputpin.h" |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <string.h> | 11 #include <string.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 | 13 |
14 /* | 14 static inline int output_unimplemented(const char* s, void* p) |
15 { | |
16 Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); | |
17 return E_NOTIMPL; | |
18 } | |
19 | |
20 /** | |
15 An object beyond interface IEnumMediaTypes. | 21 An object beyond interface IEnumMediaTypes. |
16 Returned by COutputPin through call IPin::EnumMediaTypes(). | 22 Returned by COutputPin through call IPin::EnumMediaTypes(). |
17 */ | 23 */ |
18 | |
19 static inline int output_unimplemented(const char* s, void* p) | |
20 { | |
21 Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); | |
22 return E_NOTIMPL; | |
23 } | |
24 | |
25 typedef struct CEnumMediaTypes | 24 typedef struct CEnumMediaTypes |
26 { | 25 { |
27 IEnumMediaTypes_vt* vt; | 26 IEnumMediaTypes_vt* vt; |
28 DECLARE_IUNKNOWN(); | 27 DECLARE_IUNKNOWN(); |
29 AM_MEDIA_TYPE type; | 28 AM_MEDIA_TYPE type; |
30 GUID interfaces[2]; | 29 GUID interfaces[2]; |
31 } CEnumMediaTypes; | 30 } CEnumMediaTypes; |
32 | 31 |
32 /** | |
33 IMemOutput interface implementation | |
34 */ | |
33 struct _COutputMemPin | 35 struct _COutputMemPin |
34 { | 36 { |
35 IMemInputPin_vt* vt; | 37 IMemInputPin_vt* vt; |
36 DECLARE_IUNKNOWN(); | 38 DECLARE_IUNKNOWN(); |
37 char** frame_pointer; | 39 char** frame_pointer; |
38 long* frame_size_pointer; | 40 long* frame_size_pointer; |
39 MemAllocator* pAllocator; | 41 MemAllocator* pAllocator; |
40 COutputPin* parent; | 42 COutputPin* parent; |
41 }; | 43 }; |
42 | 44 |
45 /** | |
46 * \brief IEnumMediaTypes:Next (retrives a specified number of media types ) | |
47 * | |
48 * \param[in] This pointer to CEnumMediaTypes object | |
49 * \param[in] cMediaTypes number of media types to retrive | |
50 * \param[out] ppMediaTypes array of AM_MEDIA_TYPE structure pointers of size cMediaTypes | |
51 * \param[out] pcFetched address of variables that receives number of returned media types | |
52 * | |
53 * \return S_OK - success | |
54 * \return S_FALSE - did not return as meny structures as requested | |
55 * \return E_INVALIDARG Invalid argument | |
56 * \return E_POINTER Null pointer | |
57 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator | |
58 * | |
59 */ | |
43 static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This, | 60 static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This, |
44 /* [in] */ ULONG cMediaTypes, | 61 /* [in] */ ULONG cMediaTypes, |
45 /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes, | 62 /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes, |
46 /* [out] */ ULONG *pcFetched) | 63 /* [out] */ ULONG *pcFetched) |
47 { | 64 { |
68 return 0; | 85 return 0; |
69 return 1; | 86 return 1; |
70 } | 87 } |
71 | 88 |
72 /* I expect that these methods are unused. */ | 89 /* I expect that these methods are unused. */ |
90 | |
91 /** | |
92 * \brief IEnumMediaTypes::Skip (skips over a specified number of media types) | |
93 * | |
94 * \param[in] This pointer to CEnumMEdiaTypes object | |
95 * \param[in] cMediaTypes number of media types to skip | |
96 * | |
97 * \return S_OK - success | |
98 * \return S_FALSE - skipped past the end of the sequence | |
99 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator | |
100 * | |
101 */ | |
73 static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This, | 102 static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This, |
74 /* [in] */ ULONG cMediaTypes) | 103 /* [in] */ ULONG cMediaTypes) |
75 { | 104 { |
76 return output_unimplemented("CEnumMediaTypes::Skip", This); | 105 return output_unimplemented("CEnumMediaTypes::Skip", This); |
77 } | 106 } |
78 | 107 |
108 /** | |
109 * \brief IEnumMediaTypes::Reset (resets enumeration sequence to beginning) | |
110 * | |
111 * \param[in] This pointer to CEnumMEdiaTypes object | |
112 * | |
113 * \return S_OK - success | |
114 * | |
115 */ | |
79 static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This) | 116 static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This) |
80 { | 117 { |
81 Debug printf("CEnumMediaTypes::Reset(%p) called\n", This); | 118 Debug printf("CEnumMediaTypes::Reset(%p) called\n", This); |
82 return 0; | 119 return 0; |
83 } | 120 } |
84 | 121 |
122 /** | |
123 * \brief IEnumMediaTypes::Clone (makes a copy of enumerator, returned object | |
124 * starts at the same position as original) | |
125 * | |
126 * \param[in] This pointer to CEnumMEdiaTypes object | |
127 * \param[out] ppEnum address of variable that receives pointer to IEnumMediaTypes interface | |
128 * | |
129 * \return S_OK - success | |
130 * \return E_OUTOFMEMRY - Insufficient memory | |
131 * \return E_POINTER - Null pointer | |
132 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator | |
133 * | |
134 */ | |
85 static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This, | 135 static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This, |
86 /* [out] */ IEnumMediaTypes **ppEnum) | 136 /* [out] */ IEnumMediaTypes **ppEnum) |
87 { | 137 { |
88 Debug printf("CEnumMediaTypes::Clone(%p) called\n", This); | 138 Debug printf("CEnumMediaTypes::Clone(%p) called\n", This); |
89 return E_NOTIMPL; | 139 return E_NOTIMPL; |
90 } | 140 } |
91 | 141 |
142 /** | |
143 * \brief CEnumMediaTypes destructor | |
144 * | |
145 * \param[in] This pointer to CEnumMediaTypes object | |
146 * | |
147 */ | |
92 static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) | 148 static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) |
93 { | 149 { |
94 free(This->vt); | 150 free(This->vt); |
95 free(This); | 151 free(This); |
96 } | 152 } |
97 | 153 |
98 // IPin->IUnknown methods | 154 // IEnumMediaTypes->IUnknown methods |
99 IMPLEMENT_IUNKNOWN(CEnumMediaTypes) | 155 IMPLEMENT_IUNKNOWN(CEnumMediaTypes) |
100 | 156 |
157 /** | |
158 * \brief CEnumMediaTypes constructor | |
159 * | |
160 * \param[in] amt media type for enumerating | |
161 * | |
162 * \return pointer to CEnumMEdiaTypes object or NULL if error occured | |
163 * | |
164 */ | |
101 static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) | 165 static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) |
102 { | 166 { |
103 CEnumMediaTypes *This = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ; | 167 CEnumMediaTypes *This = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ; |
104 | 168 |
105 if (!This) | 169 if (!This) |
130 } | 194 } |
131 | 195 |
132 | 196 |
133 /************* | 197 /************* |
134 * COutputPin | 198 * COutputPin |
199 * | |
200 * WARNING: | |
201 * This is implementation of INPUT pin in DirectShow's terms | |
202 * | |
135 *************/ | 203 *************/ |
136 | 204 |
137 | 205 |
206 /** | |
207 * | |
208 * \brief IUnknown::QueryInterface (query object for interface) | |
209 * \param[in] This pointer to IUnknown interface | |
210 * \param[in] iid GUID of requested interface | |
211 * \param[out] ppv receives pointer to interface | |
212 * | |
213 * \return S_OK - success (and *ppv contains valid pointer) | |
214 * \return E_NOINTERFACE - interface not found (and *ppv was set NULL) | |
215 * | |
216 * \note | |
217 * Make sure to call Release on received interface when you are done | |
218 * | |
219 */ | |
138 static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) | 220 static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) |
139 { | 221 { |
140 COutputPin* p = (COutputPin*) This; | 222 COutputPin* p = (COutputPin*) This; |
141 | 223 |
142 Debug printf("COutputPin_QueryInterface(%p) called\n", This); | 224 Debug printf("COutputPin_QueryInterface(%p) called\n", This); |
165 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); | 247 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); |
166 return E_NOINTERFACE; | 248 return E_NOINTERFACE; |
167 } | 249 } |
168 | 250 |
169 // IPin methods | 251 // IPin methods |
252 | |
253 /** | |
254 * \brief IPin::Connect (connects pin to another pin) | |
255 * | |
256 * \param[in] This pointer to IPin interface | |
257 * \param[in] pReceivePin pointer to IPin interface of remote pin | |
258 * \param[in] pmt suggested media type for link. Can be NULL (any media type) | |
259 * | |
260 * \return S_OK - success. | |
261 * \return VFW_E_ALREADY_CONNECTED - pin already connected | |
262 * \return VFW_E_NOT_STOPPED - filter is active | |
263 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable | |
264 * \return Apropriate error code otherwise. | |
265 * | |
266 */ | |
170 static HRESULT STDCALL COutputPin_Connect(IPin * This, | 267 static HRESULT STDCALL COutputPin_Connect(IPin * This, |
171 /* [in] */ IPin *pReceivePin, | 268 /* [in] */ IPin *pReceivePin, |
172 /* [in] */ /* const */ AM_MEDIA_TYPE *pmt) | 269 /* [in] */ /* const */ AM_MEDIA_TYPE *pmt) |
173 { | 270 { |
174 Debug printf("COutputPin_Connect() called\n"); | 271 Debug printf("COutputPin_Connect() called\n"); |
183 //return E_NOTIMPL; | 280 //return E_NOTIMPL; |
184 return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX | 281 return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX |
185 // if I put return 0; here, it crashes | 282 // if I put return 0; here, it crashes |
186 } | 283 } |
187 | 284 |
285 /** | |
286 * \brief IPin::ReceiveConnection (accepts a connection from another pin) | |
287 * | |
288 * \param[in] This pointer to IPin interface | |
289 * \param[in] pConnector connecting pin's IPin interface | |
290 * \param[in] pmt suggested media type for connection | |
291 * | |
292 * \return S_OK - success | |
293 * \return E_POINTER - Null pointer | |
294 * \return VFW_E_ALREADY_CONNECTED - pin already connected | |
295 * \return VFW_E_NOT_STOPPED - filter is active | |
296 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable | |
297 * | |
298 * \note | |
299 * When returning S_OK method should also do the following: | |
300 * - store media type and return the same type in IPin::ConnectionMediaType | |
301 * - store pConnector and return it in IPin::ConnectedTo | |
302 * | |
303 */ | |
188 static HRESULT STDCALL COutputPin_ReceiveConnection(IPin * This, | 304 static HRESULT STDCALL COutputPin_ReceiveConnection(IPin * This, |
189 /* [in] */ IPin *pConnector, | 305 /* [in] */ IPin *pConnector, |
190 /* [in] */ const AM_MEDIA_TYPE *pmt) | 306 /* [in] */ const AM_MEDIA_TYPE *pmt) |
191 { | 307 { |
192 Debug printf("COutputPin_ReceiveConnection(%p) called\n", This); | 308 Debug printf("COutputPin_ReceiveConnection(%p) called\n", This); |
193 ((COutputPin*)This)->remote = pConnector; | 309 ((COutputPin*)This)->remote = pConnector; |
194 return 0; | 310 return 0; |
195 } | 311 } |
196 | 312 |
313 /** | |
314 * \brief IPin::Disconnect (accepts a connection from another pin) | |
315 * | |
316 * \param[in] This pointer to IPin interface | |
317 * | |
318 * \return S_OK - success | |
319 * \return S_FALSE - pin was not connected | |
320 * \return VFW_E_NOT_STOPPED - filter is active | |
321 * | |
322 * \note | |
323 * To break connection you have to also call Disconnect on other pin | |
324 */ | |
197 static HRESULT STDCALL COutputPin_Disconnect(IPin * This) | 325 static HRESULT STDCALL COutputPin_Disconnect(IPin * This) |
198 { | 326 { |
199 Debug printf("COutputPin_Disconnect(%p) called\n", This); | 327 Debug printf("COutputPin_Disconnect(%p) called\n", This); |
200 return 1; | 328 return 1; |
201 } | 329 } |
202 | 330 |
331 /** | |
332 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist) | |
333 * | |
334 * \param[in] This pointer to IPin interface | |
335 * \param[out] pPin pointer to remote pin's IPin interface | |
336 * | |
337 * \return S_OK - success | |
338 * \return E_POINTER - Null pointer | |
339 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
340 * | |
341 * \note | |
342 * Caller must call Release on received IPin, when done | |
343 */ | |
203 static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This, | 344 static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This, |
204 /* [out] */ IPin **pPin) | 345 /* [out] */ IPin **pPin) |
205 { | 346 { |
206 Debug printf("COutputPin_ConnectedTo(%p) called\n", This); | 347 Debug printf("COutputPin_ConnectedTo(%p) called\n", This); |
207 if (!pPin) | 348 if (!pPin) |
208 return E_INVALIDARG; | 349 return E_INVALIDARG; |
209 *pPin = ((COutputPin*)This)->remote; | 350 *pPin = ((COutputPin*)This)->remote; |
210 return 0; | 351 return 0; |
211 } | 352 } |
212 | 353 |
354 /** | |
355 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist) | |
356 * | |
357 * \param[in] This pointer to IPin interface | |
358 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type | |
359 * | |
360 * \return S_OK - success | |
361 * \return E_POINTER - Null pointer | |
362 * \return VFW_E_NOT_CONNECTED - pin is not connected | |
363 * | |
364 */ | |
213 static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This, | 365 static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This, |
214 /* [out] */ AM_MEDIA_TYPE *pmt) | 366 /* [out] */ AM_MEDIA_TYPE *pmt) |
215 { | 367 { |
216 Debug printf("CInputPin::ConnectionMediaType() called\n"); | 368 Debug printf("CInputPin::ConnectionMediaType() called\n"); |
217 if (!pmt) | 369 if (!pmt) |
223 memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat); | 375 memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat); |
224 } | 376 } |
225 return 0; | 377 return 0; |
226 } | 378 } |
227 | 379 |
380 /** | |
381 * \brief IPin::QueryPinInfo (retrieves information about the pin) | |
382 * | |
383 * \param[in] This pointer to IPin interface | |
384 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info | |
385 * | |
386 * \return S_OK - success | |
387 * \return E_POINTER - Null pointer | |
388 * | |
389 * \note | |
390 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done | |
391 * | |
392 */ | |
228 static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This, | 393 static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This, |
229 /* [out] */ PIN_INFO *pInfo) | 394 /* [out] */ PIN_INFO *pInfo) |
230 { | 395 { |
231 return output_unimplemented("COutputPin_QueryPinInfo", This); | 396 return output_unimplemented("COutputPin_QueryPinInfo", This); |
232 } | 397 } |
233 | 398 |
399 /** | |
400 * \brief IPin::QueryDirection (retrieves pin direction) | |
401 * | |
402 * \param[in] This pointer to IPin interface | |
403 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) | |
404 * | |
405 * \return S_OK - success | |
406 * \return E_POINTER - Null pointer | |
407 * | |
408 */ | |
234 static HRESULT STDCALL COutputPin_QueryDirection(IPin * This, | 409 static HRESULT STDCALL COutputPin_QueryDirection(IPin * This, |
235 /* [out] */ PIN_DIRECTION *pPinDir) | 410 /* [out] */ PIN_DIRECTION *pPinDir) |
236 { | 411 { |
237 Debug printf("COutputPin_QueryDirection(%p) called\n", This); | 412 Debug printf("COutputPin_QueryDirection(%p) called\n", This); |
238 if (!pPinDir) | 413 if (!pPinDir) |
239 return E_INVALIDARG; | 414 return E_INVALIDARG; |
240 *pPinDir = PINDIR_INPUT; | 415 *pPinDir = PINDIR_INPUT; |
241 return 0; | 416 return 0; |
242 } | 417 } |
243 | 418 |
419 /** | |
420 * \brief IPin::QueryId (retrieves pin identificator) | |
421 * | |
422 * \param[in] This pointer to IPin interface | |
423 * \param[out] Id adress of variable, that receives string with pin's Id. | |
424 * | |
425 * \return S_OK - success | |
426 * \return E_OUTOFMEMORY - Insufficient memory | |
427 * \return E_POINTER - Null pointer | |
428 * | |
429 * \note | |
430 * Pin's Id is not the same as pin's name | |
431 * | |
432 */ | |
244 static HRESULT STDCALL COutputPin_QueryId(IPin * This, | 433 static HRESULT STDCALL COutputPin_QueryId(IPin * This, |
245 /* [out] */ LPWSTR *Id) | 434 /* [out] */ LPWSTR *Id) |
246 { | 435 { |
247 return output_unimplemented("COutputPin_QueryId", This); | 436 return output_unimplemented("COutputPin_QueryId", This); |
248 } | 437 } |
249 | 438 |
439 /** | |
440 * \brief IPin::QueryAccept (determines can media type be accepted or not) | |
441 * | |
442 * \param[in] This pointer to IPin interface | |
443 * \param[in] pmt Media type to check | |
444 * | |
445 * \return S_OK - success | |
446 * \return S_FALSE - pin rejects media type | |
447 * | |
448 */ | |
250 static HRESULT STDCALL COutputPin_QueryAccept(IPin * This, | 449 static HRESULT STDCALL COutputPin_QueryAccept(IPin * This, |
251 /* [in] */ const AM_MEDIA_TYPE *pmt) | 450 /* [in] */ const AM_MEDIA_TYPE *pmt) |
252 { | 451 { |
253 return output_unimplemented("COutputPin_QueryAccept", This); | 452 return output_unimplemented("COutputPin_QueryAccept", This); |
254 } | 453 } |
255 | 454 |
455 /** | |
456 * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types) | |
457 * | |
458 * \param[in] This pointer to IPin interface | |
459 * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface | |
460 * | |
461 * \return S_OK - success | |
462 * \return E_OUTOFMEMORY - Insufficient memory | |
463 * \return E_POINTER - Null pointer | |
464 * | |
465 * \note | |
466 * Caller must call Release on received interface when done | |
467 * | |
468 */ | |
256 static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This, | 469 static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This, |
257 /* [out] */ IEnumMediaTypes **ppEnum) | 470 /* [out] */ IEnumMediaTypes **ppEnum) |
258 { | 471 { |
259 Debug printf("COutputPin_EnumMediaTypes() called\n"); | 472 Debug printf("COutputPin_EnumMediaTypes() called\n"); |
260 if (!ppEnum) | 473 if (!ppEnum) |
261 return E_INVALIDARG; | 474 return E_INVALIDARG; |
262 *ppEnum = (IEnumMediaTypes*) CEnumMediaTypesCreate(&((COutputPin*)This)->type); | 475 *ppEnum = (IEnumMediaTypes*) CEnumMediaTypesCreate(&((COutputPin*)This)->type); |
263 return 0; | 476 return 0; |
264 } | 477 } |
265 | 478 |
479 /** | |
480 * \brief IPin::QueryInternalConnections (retries pin's internal connections) | |
481 * | |
482 * \param[in] This pointer to IPin interface | |
483 * \param[out] apPin Array that receives pins, internally connected to this | |
484 * \param[in,out] nPint Size of an array | |
485 * | |
486 * \return S_OK - success | |
487 * \return S_FALSE - pin rejects media type | |
488 * \return E_NOTIMPL - not implemented | |
489 * | |
490 */ | |
266 static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This, | 491 static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This, |
267 /* [out] */ IPin **apPin, | 492 /* [out] */ IPin **apPin, |
268 /* [out][in] */ ULONG *nPin) | 493 /* [out][in] */ ULONG *nPin) |
269 { | 494 { |
270 return output_unimplemented("COutputPin_QueryInternalConnections", This); | 495 return output_unimplemented("COutputPin_QueryInternalConnections", This); |
271 } | 496 } |
272 | 497 |
498 /** | |
499 * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command) | |
500 * | |
501 * \param[in] This pointer to IPin interface | |
502 * | |
503 * \return S_OK - success | |
504 * \return E_UNEXPECTED - The pin is output pin | |
505 * | |
506 * \note | |
507 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, | |
508 * IMemAllocator::GetBuffer runs in different (streaming) thread then other | |
509 * methods (application thread). | |
510 * IMemoryInputPin::NewSegment runs either in streaming or application thread. | |
511 * Developer must use critical sections for thread-safing work. | |
512 * | |
513 */ | |
273 static HRESULT STDCALL COutputPin_EndOfStream(IPin * This) | 514 static HRESULT STDCALL COutputPin_EndOfStream(IPin * This) |
274 { | 515 { |
275 return output_unimplemented("COutputPin_EndOfStream", This); | 516 return output_unimplemented("COutputPin_EndOfStream", This); |
276 } | 517 } |
277 | 518 |
519 /** | |
520 * \brief IPin::BeginFlush (begins a flush operation) | |
521 * | |
522 * \param[in] This pointer to IPin interface | |
523 * | |
524 * \return S_OK - success | |
525 * \return E_UNEXPECTED - The pin is output pin | |
526 * | |
527 */ | |
278 static HRESULT STDCALL COutputPin_BeginFlush(IPin * This) | 528 static HRESULT STDCALL COutputPin_BeginFlush(IPin * This) |
279 { | 529 { |
280 return output_unimplemented("COutputPin_BeginFlush", This); | 530 return output_unimplemented("COutputPin_BeginFlush", This); |
281 } | 531 } |
282 | 532 |
533 /** | |
534 * \brief IPin::BeginFlush (ends a flush operation) | |
535 * | |
536 * \param[in] This pointer to IPin interface | |
537 * | |
538 * \return S_OK - success | |
539 * \return E_UNEXPECTED - The pin is output pin | |
540 * | |
541 */ | |
283 static HRESULT STDCALL COutputPin_EndFlush(IPin * This) | 542 static HRESULT STDCALL COutputPin_EndFlush(IPin * This) |
284 { | 543 { |
285 return output_unimplemented("COutputPin_EndFlush", This); | 544 return output_unimplemented("COutputPin_EndFlush", This); |
286 } | 545 } |
287 | 546 |
547 /** | |
548 * \brief IPin::BeginFlush (media sample received after this call grouped as segment with common | |
549 * start,stop time and rate) | |
550 * | |
551 * \param[in] This pointer to IPin interface | |
552 * \param[in] tStart start time of new segment | |
553 * \param[in] tStop end time of new segment | |
554 * \param[in] dRate rate at wich segment should be processed | |
555 * | |
556 * \return S_OK - success | |
557 * \return E_UNEXPECTED - The pin is output pin | |
558 * | |
559 */ | |
288 static HRESULT STDCALL COutputPin_NewSegment(IPin * This, | 560 static HRESULT STDCALL COutputPin_NewSegment(IPin * This, |
289 /* [in] */ REFERENCE_TIME tStart, | 561 /* [in] */ REFERENCE_TIME tStart, |
290 /* [in] */ REFERENCE_TIME tStop, | 562 /* [in] */ REFERENCE_TIME tStop, |
291 /* [in] */ double dRate) | 563 /* [in] */ double dRate) |
292 { | 564 { |
297 | 569 |
298 | 570 |
299 | 571 |
300 // IMemInputPin->IUnknown methods | 572 // IMemInputPin->IUnknown methods |
301 | 573 |
574 /** | |
575 * \brief IUnknown::QueryInterface (query object for interface) | |
576 * | |
577 * \param[in] This pointer to IUnknown interface | |
578 * \param[in] iid GUID of requested interface | |
579 * \param[out] ppv receives pointer to interface | |
580 * | |
581 * \return S_OK - success (and *ppv contains valid pointer) | |
582 * \return E_NOINTERFACE - interface not found (and *ppv was set NULL) | |
583 * | |
584 * \note | |
585 * Make sure to call Release on received interface when you are done | |
586 * | |
587 */ | |
302 static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) | 588 static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) |
303 { | 589 { |
304 COutputPin* p = (COutputPin*)This; | 590 COutputPin* p = (COutputPin*)This; |
305 | 591 |
306 Debug printf("COutputPin_M_QueryInterface(%p) called\n", This); | 592 Debug printf("COutputPin_M_QueryInterface(%p) called\n", This); |
336 return E_NOINTERFACE; | 622 return E_NOINTERFACE; |
337 } | 623 } |
338 | 624 |
339 // IMemInputPin methods | 625 // IMemInputPin methods |
340 | 626 |
627 /** | |
628 * \brief IMemInputPin::GetAllocator (retrives memory allocator, proposed by pin) | |
629 * | |
630 * \param[in] This pointer to IMemInputPin interface | |
631 * \param[out] ppAllocator address of variable that receives allocator's IMemAllocator interface | |
632 * | |
633 * \return S_OK - success | |
634 * \return VFW_E_NO_ALLOCATOR - No allocator | |
635 * | |
636 * \note | |
637 * Make sure to call Release on received interface when you are done | |
638 * | |
639 */ | |
341 static HRESULT STDCALL COutputPin_GetAllocator(IMemInputPin* This, | 640 static HRESULT STDCALL COutputPin_GetAllocator(IMemInputPin* This, |
342 /* [out] */ IMemAllocator** ppAllocator) | 641 /* [out] */ IMemAllocator** ppAllocator) |
343 { | 642 { |
344 Debug printf("COutputPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator); | 643 Debug printf("COutputPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator); |
345 *ppAllocator = (IMemAllocator*) MemAllocatorCreate(); | 644 *ppAllocator = (IMemAllocator*) MemAllocatorCreate(); |
346 return 0; | 645 return 0; |
347 } | 646 } |
348 | 647 |
648 /** | |
649 * | |
650 * \brief IMemInputPin::NotifyAllocator (specifies an allocator for the connection) | |
651 * | |
652 * \param[in] This pointer to IMemInputPin interface | |
653 * \param[in] pAllocator allocator's IMemAllocator interface | |
654 * \param[in] bReadOnly specifies whether samples from allocator are readonly | |
655 * | |
656 * \return S_OK - success | |
657 * \return Apropriate error code otherwise | |
658 * | |
659 */ | |
349 static HRESULT STDCALL COutputPin_NotifyAllocator(IMemInputPin* This, | 660 static HRESULT STDCALL COutputPin_NotifyAllocator(IMemInputPin* This, |
350 /* [in] */ IMemAllocator* pAllocator, | 661 /* [in] */ IMemAllocator* pAllocator, |
351 /* [in] */ int bReadOnly) | 662 /* [in] */ int bReadOnly) |
352 { | 663 { |
353 Debug printf("COutputPin_NotifyAllocator(%p, %p) called\n", This, pAllocator); | 664 Debug printf("COutputPin_NotifyAllocator(%p, %p) called\n", This, pAllocator); |
354 ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator; | 665 ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator; |
355 return 0; | 666 return 0; |
356 } | 667 } |
357 | 668 |
669 /** | |
670 * \brief IMemInputPin::GetAllocatorRequirements (retrieves allocator properties requested by | |
671 * input pin) | |
672 * | |
673 * \param[in] This pointer to IMemInputPin interface | |
674 * \param[out] pProps pointer to a structure that receives allocator properties | |
675 * | |
676 * \return S_OK - success | |
677 * \return E_NOTIMPL - Not implemented | |
678 * \return E_POINTER - Null pointer | |
679 * | |
680 */ | |
358 static HRESULT STDCALL COutputPin_GetAllocatorRequirements(IMemInputPin* This, | 681 static HRESULT STDCALL COutputPin_GetAllocatorRequirements(IMemInputPin* This, |
359 /* [out] */ ALLOCATOR_PROPERTIES* pProps) | 682 /* [out] */ ALLOCATOR_PROPERTIES* pProps) |
360 { | 683 { |
361 return output_unimplemented("COutputPin_GetAllocatorRequirements", This); | 684 return output_unimplemented("COutputPin_GetAllocatorRequirements", This); |
362 } | 685 } |
363 | 686 |
687 /** | |
688 * \brief IMemInputPin::Receive (receives the next media sample int thre stream) | |
689 * | |
690 * \param[in] This pointer to IMemInputPin interface | |
691 * \param[in] pSample pointer to sample's IMediaSample interface | |
692 * | |
693 * \return S_OK - success | |
694 * \return S_FALSE - The sample was rejected | |
695 * \return E_POINTER - Null pointer | |
696 * \return VFW_E_INVALIDMEDIATYPE - invalid media type | |
697 * \return VFW_E_RUNTIME_ERROR - run-time error occured | |
698 * \return VFW_E_WRONG_STATE - pin is stopped | |
699 * | |
700 * \remarks | |
701 * Method san do on of the following: | |
702 * - reject sample | |
703 * - accept sample and process it in another thread | |
704 * - accept sample and process it before returning | |
705 * | |
706 * In second case method should increase reference count for sample (through AddRef) | |
707 * In the last case method might block indefinitely. If this might | |
708 * happen IMemInpuPin::ReceiveCAnBlock returns S_OK | |
709 * | |
710 * \note | |
711 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, | |
712 * IMemAllocator::GetBuffer runs in different (streaming) thread then other | |
713 * methods (application thread). | |
714 * IMemoryInputPin::NewSegment runs either in streaming or application thread. | |
715 * Developer must use critical sections for thread-safing work. | |
716 * | |
717 */ | |
364 static HRESULT STDCALL COutputPin_Receive(IMemInputPin* This, | 718 static HRESULT STDCALL COutputPin_Receive(IMemInputPin* This, |
365 /* [in] */ IMediaSample* pSample) | 719 /* [in] */ IMediaSample* pSample) |
366 { | 720 { |
367 COutputMemPin* mp = (COutputMemPin*)This; | 721 COutputMemPin* mp = (COutputMemPin*)This; |
368 char* pointer; | 722 char* pointer; |
394 // pSample->vt->Release((IUnknown*)pSample); | 748 // pSample->vt->Release((IUnknown*)pSample); |
395 | 749 |
396 return 0; | 750 return 0; |
397 } | 751 } |
398 | 752 |
753 /** | |
754 * \brief IMemInputPin::ReceiveMultiple (receives multiple samples in the stream) | |
755 * | |
756 * \param[in] This pointer to IMemInputPin interface | |
757 * \param[in] pSamples pointer to array with samples | |
758 * \param[in] nSamples number of samples in array | |
759 * \param[out] nSamplesProcessed number of processed samples | |
760 * | |
761 * \return S_OK - success | |
762 * \return S_FALSE - The sample was rejected | |
763 * \return E_POINTER - Null pointer | |
764 * \return VFW_E_INVALIDMEDIATYPE - invalid media type | |
765 * \return VFW_E_RUNTIME_ERROR - run-time error occured | |
766 * \return VFW_E_WRONG_STATE - pin is stopped | |
767 * | |
768 * \remarks | |
769 * This method behaves like IMemInputPin::Receive but for array of samples | |
770 * | |
771 * \note | |
772 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, | |
773 * IMemAllocator::GetBuffer runs in different (streaming) thread then other | |
774 * methods (application thread). | |
775 * IMemoryInputPin::NewSegment runs either in streaming or application thread. | |
776 * Developer must use critical sections for thread-safing work. | |
777 * | |
778 */ | |
399 static HRESULT STDCALL COutputPin_ReceiveMultiple(IMemInputPin * This, | 779 static HRESULT STDCALL COutputPin_ReceiveMultiple(IMemInputPin * This, |
400 /* [size_is][in] */ IMediaSample **pSamples, | 780 /* [size_is][in] */ IMediaSample **pSamples, |
401 /* [in] */ long nSamples, | 781 /* [in] */ long nSamples, |
402 /* [out] */ long *nSamplesProcessed) | 782 /* [out] */ long *nSamplesProcessed) |
403 { | 783 { |
404 return output_unimplemented("COutputPin_ReceiveMultiple", This); | 784 return output_unimplemented("COutputPin_ReceiveMultiple", This); |
405 } | 785 } |
406 | 786 |
787 /** | |
788 * \brief IMemInputPin::ReceiveCanBlock (determines whether IMemInputPin:::Receive might block) | |
789 * | |
790 * \param[in] This pointer to IMemInputPin interface | |
791 * | |
792 * \return S_OK - the pin might block | |
793 * \return S_FALSE - the pin will not block | |
794 * | |
795 */ | |
407 static HRESULT STDCALL COutputPin_ReceiveCanBlock(IMemInputPin * This) | 796 static HRESULT STDCALL COutputPin_ReceiveCanBlock(IMemInputPin * This) |
408 { | 797 { |
409 return output_unimplemented("COutputPin_ReceiveCanBlock", This); | 798 return output_unimplemented("COutputPin_ReceiveCanBlock", This); |
410 } | 799 } |
411 | 800 |
801 /** | |
802 * \brief COutputPin::SetFramePointer (sets internal frame pointer to an external buffer) | |
803 * | |
804 * \param[in] This pointer to COutputPin class | |
805 * \param[in] z new pointer | |
806 * | |
807 */ | |
412 static void COutputPin_SetFramePointer(COutputPin* This, char** z) | 808 static void COutputPin_SetFramePointer(COutputPin* This, char** z) |
413 { | 809 { |
414 This->mempin->frame_pointer = z; | 810 This->mempin->frame_pointer = z; |
415 } | 811 } |
416 | 812 |
813 /** | |
814 * \brief COutputPin::SetFramePointer2 (sets allocator's pointer to an external buffer) | |
815 * | |
816 * \param[in] This pointer to COutputPin class | |
817 * \param[in] z new pointer | |
818 * | |
819 */ | |
417 static void COutputPin_SetPointer2(COutputPin* This, char* p) | 820 static void COutputPin_SetPointer2(COutputPin* This, char* p) |
418 { | 821 { |
419 if (This->mempin->pAllocator) | 822 if (This->mempin->pAllocator) |
420 // fixme | 823 // fixme |
421 This->mempin->pAllocator->SetPointer(This->mempin->pAllocator, p); | 824 This->mempin->pAllocator->SetPointer(This->mempin->pAllocator, p); |
422 } | 825 } |
423 | 826 |
827 /** | |
828 * \brief COutputPin::SetFrameSizePointer (sets pointer to variable that receives frame size) | |
829 * | |
830 * \param[in] This pointer to COutputPin class | |
831 * \param[in] z new pointer | |
832 * | |
833 */ | |
424 static void COutputPin_SetFrameSizePointer(COutputPin* This, long* z) | 834 static void COutputPin_SetFrameSizePointer(COutputPin* This, long* z) |
425 { | 835 { |
426 This->mempin->frame_size_pointer = z; | 836 This->mempin->frame_size_pointer = z; |
427 } | 837 } |
428 | 838 |
839 /** | |
840 * \brief COutputPin::SetNewFormat(sets new media format for the pin) | |
841 * | |
842 * \param[in] This pointer to COutputPin class | |
843 * \param[in] amt new media format | |
844 * | |
845 */ | |
429 static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt) | 846 static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt) |
430 { | 847 { |
431 This->type = *amt; | 848 This->type = *amt; |
432 } | 849 } |
433 | 850 |
851 /** | |
852 * \brief COutputPin destructor | |
853 * | |
854 * \param[in] This pointer to COutputPin class | |
855 * | |
856 */ | |
434 static void COutputPin_Destroy(COutputPin* This) | 857 static void COutputPin_Destroy(COutputPin* This) |
435 { | 858 { |
436 if (This->mempin->vt) | 859 if (This->mempin->vt) |
437 free(This->mempin->vt); | 860 free(This->mempin->vt); |
438 if (This->mempin) | 861 if (This->mempin) |
440 if (This->vt) | 863 if (This->vt) |
441 free(This->vt); | 864 free(This->vt); |
442 free(This); | 865 free(This); |
443 } | 866 } |
444 | 867 |
868 /** | |
869 * \brief IUnknown::AddRef (increases reference counter for interface) | |
870 * | |
871 * \param[in] This pointer to IUnknown class | |
872 * | |
873 * \return new value of reference counter | |
874 * | |
875 * \remarks | |
876 * Return value should be used only for debug purposes | |
877 * | |
878 */ | |
445 static HRESULT STDCALL COutputPin_AddRef(IUnknown* This) | 879 static HRESULT STDCALL COutputPin_AddRef(IUnknown* This) |
446 { | 880 { |
447 Debug printf("COutputPin_AddRef(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); | 881 Debug printf("COutputPin_AddRef(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); |
448 ((COutputPin*)This)->refcount++; | 882 ((COutputPin*)This)->refcount++; |
449 return 0; | 883 return 0; |
450 } | 884 } |
451 | 885 |
886 /** | |
887 * \brief IUnknown::Release (desreases reference counter for interface) | |
888 * | |
889 * \param[in] This pointer to IUnknown class | |
890 * | |
891 * \return new value of reference counter | |
892 * | |
893 * \remarks | |
894 * When reference counter reaches zero calls destructor | |
895 * Return value should be used only for debug purposes | |
896 * | |
897 */ | |
452 static HRESULT STDCALL COutputPin_Release(IUnknown* This) | 898 static HRESULT STDCALL COutputPin_Release(IUnknown* This) |
453 { | 899 { |
454 Debug printf("COutputPin_Release(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); | 900 Debug printf("COutputPin_Release(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); |
455 if (--((COutputPin*)This)->refcount <= 0) | 901 if (--((COutputPin*)This)->refcount <= 0) |
456 COutputPin_Destroy((COutputPin*)This); | 902 COutputPin_Destroy((COutputPin*)This); |
457 | 903 |
458 return 0; | 904 return 0; |
459 } | 905 } |
460 | 906 |
907 /** | |
908 * \brief IUnknown::AddRef (increases reference counter for interface) | |
909 * | |
910 * \param[in] This pointer to IUnknown class | |
911 * | |
912 * \return new value of reference counter | |
913 * | |
914 * \remarks | |
915 * Return value should be used only for debug purposes | |
916 * | |
917 */ | |
461 static HRESULT STDCALL COutputPin_M_AddRef(IUnknown* This) | 918 static HRESULT STDCALL COutputPin_M_AddRef(IUnknown* This) |
462 { | 919 { |
463 COutputMemPin* p = (COutputMemPin*) This; | 920 COutputMemPin* p = (COutputMemPin*) This; |
464 Debug printf("COutputPin_MAddRef(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount); | 921 Debug printf("COutputPin_MAddRef(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount); |
465 p->parent->refcount++; | 922 p->parent->refcount++; |
466 return 0; | 923 return 0; |
467 } | 924 } |
468 | 925 |
926 /** | |
927 * \brief IUnknown::Release (desreases reference counter for interface) | |
928 * | |
929 * \param[in] This pointer to IUnknown class | |
930 * | |
931 * \return new value of reference counter | |
932 * | |
933 * \remarks | |
934 * When reference counter reaches zero calls destructor | |
935 * Return value should be used only for debug purposes | |
936 * | |
937 */ | |
469 static HRESULT STDCALL COutputPin_M_Release(IUnknown* This) | 938 static HRESULT STDCALL COutputPin_M_Release(IUnknown* This) |
470 { | 939 { |
471 COutputMemPin* p = (COutputMemPin*) This; | 940 COutputMemPin* p = (COutputMemPin*) This; |
472 Debug printf("COutputPin_MRelease(%p) called (%p, %d)\n", | 941 Debug printf("COutputPin_MRelease(%p) called (%p, %d)\n", |
473 p, p->parent, p->parent->refcount); | 942 p, p->parent, p->parent->refcount); |
474 if (--p->parent->refcount <= 0) | 943 if (--p->parent->refcount <= 0) |
475 COutputPin_Destroy(p->parent); | 944 COutputPin_Destroy(p->parent); |
476 return 0; | 945 return 0; |
477 } | 946 } |
478 | 947 |
948 /** | |
949 * \brief COutputPin constructor | |
950 * | |
951 * \param[in] amt media type for pin | |
952 * | |
953 * \return pointer to COutputPin if success | |
954 * \return NULL if error occured | |
955 * | |
956 */ | |
479 COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) | 957 COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) |
480 { | 958 { |
481 COutputPin* This = (COutputPin*) malloc(sizeof(COutputPin)); | 959 COutputPin* This = (COutputPin*) malloc(sizeof(COutputPin)); |
482 IMemInputPin_vt* ivt; | 960 IMemInputPin_vt* ivt; |
483 | 961 |