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