[KSPROXY]
[reactos.git] / reactos / dll / directx / ksproxy / input_pin.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/input_cpp.cpp
5 * PURPOSE: InputPin of Proxy Filter
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9 #include "precomp.h"
10
11 const GUID IID_IKsPinPipe = {0xe539cd90, 0xa8b4, 0x11d1, {0x81, 0x89, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}};
12 const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
13
14
15 #ifndef _MSC_VER
16
17 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
18
19 KSPIN_INTERFACE StandardPinInterface =
20 {
21 {STATIC_KSINTERFACESETID_Standard},
22 KSINTERFACE_STANDARD_STREAMING,
23 0
24 };
25
26 KSPIN_MEDIUM StandardPinMedium =
27 {
28 {STATIC_KSMEDIUMSETID_Standard},
29 KSMEDIUM_TYPE_ANYINSTANCE,
30 0
31 };
32
33 #else
34
35 KSPIN_INTERFACE StandardPinInterface =
36 {
37 STATIC_KSINTERFACESETID_Standard,
38 KSINTERFACE_STANDARD_STREAMING,
39 0
40 };
41
42 KSPIN_MEDIUM StandardPinMedium =
43 {
44 STATIC_KSMEDIUMSETID_Standard,
45 KSMEDIUM_TYPE_ANYINSTANCE,
46 0
47 };
48
49 #endif
50
51 class CInputPin : public IPin,
52 public IKsPropertySet,
53 public IKsControl,
54 public IKsObject,
55 public IKsPinEx,
56 public IMemInputPin,
57 public IKsPinPipe,
58 public IKsPinFactory,
59 public IStreamBuilder,
60 public IKsAggregateControl,
61 public IQualityControl,
62 public ISpecifyPropertyPages
63 {
64 public:
65 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
66
67 STDMETHODIMP_(ULONG) AddRef()
68 {
69 InterlockedIncrement(&m_Ref);
70 return m_Ref;
71 }
72 STDMETHODIMP_(ULONG) Release()
73 {
74 InterlockedDecrement(&m_Ref);
75 if (!m_Ref)
76 {
77 delete this;
78 return 0;
79 }
80 return m_Ref;
81 }
82
83 //IKsPinPipe
84 HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
85 HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
86 IPin* STDMETHODCALLTYPE KsGetConnectedPin();
87 IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation);
88 HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator);
89 ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag();
90 HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag);
91 GUID STDMETHODCALLTYPE KsGetPinBusCache();
92 HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus);
93 PWCHAR STDMETHODCALLTYPE KsGetPinName();
94 PWCHAR STDMETHODCALLTYPE KsGetFilterName();
95
96 //IPin methods
97 HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
98 HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
99 HRESULT STDMETHODCALLTYPE Disconnect();
100 HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin);
101 HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
102 HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
103 HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
104 HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
105 HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
106 HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
107 HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
108 HRESULT STDMETHODCALLTYPE EndOfStream();
109 HRESULT STDMETHODCALLTYPE BeginFlush();
110 HRESULT STDMETHODCALLTYPE EndFlush();
111 HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
112
113 // ISpecifyPropertyPages
114 HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
115
116 //IKsObject methods
117 HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
118
119 //IKsPropertySet
120 HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData);
121 HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned);
122 HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);
123
124 //IKsControl
125 HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
126 HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
127 HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
128
129 //IKsPin
130 HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList);
131 HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList);
132 HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium);
133 HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium);
134 HRESULT STDMETHODCALLTYPE KsPropagateAcquire();
135 HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags);
136 HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment);
137 IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation);
138 HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator);
139 HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator();
140 LONG STDMETHODCALLTYPE KsIncrementPendingIoCount();
141 LONG STDMETHODCALLTYPE KsDecrementPendingIoCount();
142 HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta);
143 // IKsPinEx
144 VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr);
145
146 //IMemInputPin
147 HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator);
148 HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly);
149 HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
150 HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample);
151 HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);
152 HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void);
153
154 //IKsPinFactory
155 HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
156
157 //IStreamBuilder
158 HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph);
159 HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
160
161 //IKsAggregateControl
162 HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass);
163 HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
164
165 //IQualityControl
166 HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q);
167 HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc);
168
169 //---------------------------------------------------------------
170 HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
171 HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
172 HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
173 CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication);
174 virtual ~CInputPin(){};
175
176 protected:
177 LONG m_Ref;
178 IBaseFilter * m_ParentFilter;
179 LPCWSTR m_PinName;
180 HANDLE m_hFilter;
181 HANDLE m_hPin;
182 ULONG m_PinId;
183 IMemAllocator * m_MemAllocator;
184 LONG m_IoCount;
185 KSPIN_COMMUNICATION m_Communication;
186 KSPIN_INTERFACE m_Interface;
187 KSPIN_MEDIUM m_Medium;
188 IPin * m_Pin;
189 BOOL m_ReadOnly;
190 IKsInterfaceHandler * m_InterfaceHandler;
191 IKsAllocatorEx * m_KsAllocatorEx;
192 ULONG m_PipeAllocatorFlag;
193 BOOL m_bPinBusCacheInitialized;
194 GUID m_PinBusCache;
195 LPWSTR m_FilterName;
196 FRAMING_PROP m_FramingProp[4];
197 PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
198 };
199
200 CInputPin::CInputPin(
201 IBaseFilter * ParentFilter,
202 LPCWSTR PinName,
203 HANDLE hFilter,
204 ULONG PinId,
205 KSPIN_COMMUNICATION Communication) : m_Ref(0),
206 m_ParentFilter(ParentFilter),
207 m_PinName(PinName),
208 m_hFilter(hFilter),
209 m_hPin(INVALID_HANDLE_VALUE),
210 m_PinId(PinId),
211 m_MemAllocator(0),
212 m_IoCount(0),
213 m_Communication(Communication),
214 m_Pin(0),
215 m_ReadOnly(0),
216 m_InterfaceHandler(0),
217 m_KsAllocatorEx(0),
218 m_PipeAllocatorFlag(0),
219 m_bPinBusCacheInitialized(0),
220 m_FilterName(0)
221 {
222 ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
223 ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
224 }
225
226 HRESULT
227 STDMETHODCALLTYPE
228 CInputPin::QueryInterface(
229 IN REFIID refiid,
230 OUT PVOID* Output)
231 {
232 *Output = NULL;
233
234 if (IsEqualGUID(refiid, IID_IUnknown) ||
235 IsEqualGUID(refiid, IID_IPin))
236 {
237 *Output = PVOID(this);
238 reinterpret_cast<IUnknown*>(*Output)->AddRef();
239 return NOERROR;
240 }
241 else if (IsEqualGUID(refiid, IID_IMemInputPin))
242 {
243 *Output = (IMemInputPin*)(this);
244 reinterpret_cast<IMemInputPin*>(*Output)->AddRef();
245 return NOERROR;
246 }
247 else if (IsEqualGUID(refiid, IID_IKsObject))
248 {
249 *Output = (IKsObject*)(this);
250 reinterpret_cast<IKsObject*>(*Output)->AddRef();
251 return NOERROR;
252 }
253 else if (IsEqualGUID(refiid, IID_IKsPropertySet))
254 {
255 *Output = (IKsPropertySet*)(this);
256 reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
257 return NOERROR;
258 }
259 else if (IsEqualGUID(refiid, IID_IKsControl))
260 {
261 *Output = (IKsControl*)(this);
262 reinterpret_cast<IKsControl*>(*Output)->AddRef();
263 return NOERROR;
264 }
265 else if (IsEqualGUID(refiid, IID_IKsPin) ||
266 IsEqualGUID(refiid, IID_IKsPinEx))
267 {
268 *Output = (IKsPinEx*)(this);
269 reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
270 return NOERROR;
271 }
272 else if (IsEqualGUID(refiid, IID_IKsPinPipe))
273 {
274 *Output = (IKsPinPipe*)(this);
275 reinterpret_cast<IKsPinPipe*>(*Output)->AddRef();
276 return NOERROR;
277 }
278 else if (IsEqualGUID(refiid, IID_IKsPinFactory))
279 {
280 *Output = (IKsPinFactory*)(this);
281 reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
282 return NOERROR;
283 }
284 #if 0
285 else if (IsEqualGUID(refiid, IID_IStreamBuilder))
286 {
287 *Output = (IStreamBuilder*)(this);
288 reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
289 return NOERROR;
290 }
291 #endif
292 else if (IsEqualGUID(refiid, IID_IKsAggregateControl))
293 {
294 *Output = (IKsAggregateControl*)(this);
295 reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef();
296 return NOERROR;
297 }
298 else if (IsEqualGUID(refiid, IID_IQualityControl))
299 {
300 *Output = (IQualityControl*)(this);
301 reinterpret_cast<IQualityControl*>(*Output)->AddRef();
302 return NOERROR;
303 }
304 else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
305 {
306 *Output = (ISpecifyPropertyPages*)(this);
307 reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
308 return NOERROR;
309 }
310
311 WCHAR Buffer[MAX_PATH];
312 LPOLESTR lpstr;
313 StringFromCLSID(refiid, &lpstr);
314 swprintf(Buffer, L"CInputPin::QueryInterface: NoInterface for %s\n", lpstr);
315 OutputDebugStringW(Buffer);
316 CoTaskMemFree(lpstr);
317
318 return E_NOINTERFACE;
319 }
320 //-------------------------------------------------------------------
321 // IQualityControl interface
322 //
323 HRESULT
324 STDMETHODCALLTYPE
325 CInputPin::Notify(
326 IBaseFilter *pSelf,
327 Quality q)
328 {
329 OutputDebugStringW(L"CInputPin::Notify NotImplemented\n");
330 return E_NOTIMPL;
331 }
332
333 HRESULT
334 STDMETHODCALLTYPE
335 CInputPin::SetSink(
336 IQualityControl *piqc)
337 {
338 OutputDebugStringW(L"CInputPin::SetSink NotImplemented\n");
339 return E_NOTIMPL;
340 }
341
342
343 //-------------------------------------------------------------------
344 // IKsAggregateControl interface
345 //
346 HRESULT
347 STDMETHODCALLTYPE
348 CInputPin::KsAddAggregate(
349 IN REFGUID AggregateClass)
350 {
351 OutputDebugStringW(L"CInputPin::KsAddAggregate NotImplemented\n");
352 return E_NOTIMPL;
353 }
354
355 HRESULT
356 STDMETHODCALLTYPE
357 CInputPin::KsRemoveAggregate(
358 REFGUID AggregateClass)
359 {
360 OutputDebugStringW(L"CInputPin::KsRemoveAggregate NotImplemented\n");
361 return E_NOTIMPL;
362 }
363
364 //-------------------------------------------------------------------
365 // IStreamBuilder
366 //
367
368 HRESULT
369 STDMETHODCALLTYPE
370 CInputPin::Render(
371 IPin *ppinOut,
372 IGraphBuilder *pGraph)
373 {
374 OutputDebugStringW(L"CInputPin::Render\n");
375 return S_OK;
376 }
377
378 HRESULT
379 STDMETHODCALLTYPE
380 CInputPin::Backout(
381 IPin *ppinOut,
382 IGraphBuilder *pGraph)
383 {
384 OutputDebugStringW(L"CInputPin::Backout\n");
385 return S_OK;
386 }
387
388 //-------------------------------------------------------------------
389 // IKsPinFactory
390 //
391
392 HRESULT
393 STDMETHODCALLTYPE
394 CInputPin::KsPinFactory(
395 ULONG* PinFactory)
396 {
397 OutputDebugStringW(L"CInputPin::KsPinFactory\n");
398 *PinFactory = m_PinId;
399 return S_OK;
400 }
401
402 //-------------------------------------------------------------------
403 // IKsPinPipe
404 //
405
406 HRESULT
407 STDMETHODCALLTYPE
408 CInputPin::KsGetPinFramingCache(
409 PKSALLOCATOR_FRAMING_EX *FramingEx,
410 PFRAMING_PROP FramingProp,
411 FRAMING_CACHE_OPS Option)
412 {
413 if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast)
414 {
415 // invalid argument
416 return E_INVALIDARG;
417 }
418
419 // get framing properties
420 *FramingProp = m_FramingProp[Option];
421 *FramingEx = m_FramingEx[Option];
422
423 return NOERROR;
424 }
425
426 HRESULT
427 STDMETHODCALLTYPE
428 CInputPin::KsSetPinFramingCache(
429 PKSALLOCATOR_FRAMING_EX FramingEx,
430 PFRAMING_PROP FramingProp,
431 FRAMING_CACHE_OPS Option)
432 {
433 ULONG Index;
434 ULONG RefCount = 0;
435
436 if (m_FramingEx[Option])
437 {
438 for(Index = 1; Index < 4; Index++)
439 {
440 if (m_FramingEx[Index] == m_FramingEx[Option])
441 RefCount++;
442 }
443
444 if (RefCount == 1)
445 {
446 // existing framing is only used once
447 CoTaskMemFree(m_FramingEx[Option]);
448 }
449 }
450
451 // store framing
452 m_FramingEx[Option] = FramingEx;
453 m_FramingProp[Option] = *FramingProp;
454
455 return S_OK;
456 }
457
458 IPin*
459 STDMETHODCALLTYPE
460 CInputPin::KsGetConnectedPin()
461 {
462 return m_Pin;
463 }
464
465 IKsAllocatorEx*
466 STDMETHODCALLTYPE
467 CInputPin::KsGetPipe(
468 KSPEEKOPERATION Operation)
469 {
470 if (Operation == KsPeekOperation_AddRef)
471 {
472 if (m_KsAllocatorEx)
473 m_KsAllocatorEx->AddRef();
474 }
475 return m_KsAllocatorEx;
476 }
477
478 HRESULT
479 STDMETHODCALLTYPE
480 CInputPin::KsSetPipe(
481 IKsAllocatorEx *KsAllocator)
482 {
483 if (KsAllocator)
484 KsAllocator->AddRef();
485
486 if (m_KsAllocatorEx)
487 m_KsAllocatorEx->Release();
488
489 m_KsAllocatorEx = KsAllocator;
490 return NOERROR;
491 }
492
493 ULONG
494 STDMETHODCALLTYPE
495 CInputPin::KsGetPipeAllocatorFlag()
496 {
497 return m_PipeAllocatorFlag;
498 }
499
500
501 HRESULT
502 STDMETHODCALLTYPE
503 CInputPin::KsSetPipeAllocatorFlag(
504 ULONG Flag)
505 {
506 m_PipeAllocatorFlag = Flag;
507 return NOERROR;
508 }
509
510 GUID
511 STDMETHODCALLTYPE
512 CInputPin::KsGetPinBusCache()
513 {
514 if (!m_bPinBusCacheInitialized)
515 {
516 CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID));
517 m_bPinBusCacheInitialized = TRUE;
518 }
519
520 return m_PinBusCache;
521 }
522
523 HRESULT
524 STDMETHODCALLTYPE
525 CInputPin::KsSetPinBusCache(
526 GUID Bus)
527 {
528 CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID));
529 return NOERROR;
530 }
531
532 PWCHAR
533 STDMETHODCALLTYPE
534 CInputPin::KsGetPinName()
535 {
536 return (PWCHAR)m_PinName;
537 }
538
539
540 PWCHAR
541 STDMETHODCALLTYPE
542 CInputPin::KsGetFilterName()
543 {
544 return m_FilterName;
545 }
546
547 //-------------------------------------------------------------------
548 // ISpecifyPropertyPages
549 //
550
551 HRESULT
552 STDMETHODCALLTYPE
553 CInputPin::GetPages(CAUUID *pPages)
554 {
555 if (!pPages)
556 return E_POINTER;
557
558 pPages->cElems = 0;
559 pPages->pElems = NULL;
560
561 return S_OK;
562 }
563
564 //-------------------------------------------------------------------
565 // IMemInputPin
566 //
567
568
569 HRESULT
570 STDMETHODCALLTYPE
571 CInputPin::GetAllocator(IMemAllocator **ppAllocator)
572 {
573 OutputDebugStringW(L"CInputPin::GetAllocator\n");
574 return VFW_E_NO_ALLOCATOR;
575 }
576
577 HRESULT
578 STDMETHODCALLTYPE
579 CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
580 {
581 if (pAllocator)
582 {
583 pAllocator->AddRef();
584 }
585
586 if (m_MemAllocator)
587 {
588 m_MemAllocator->Release();
589 }
590
591 m_MemAllocator = pAllocator;
592 m_ReadOnly = bReadOnly;
593 return NOERROR;
594 }
595
596 HRESULT
597 STDMETHODCALLTYPE
598 CInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
599 {
600 KSALLOCATOR_FRAMING Framing;
601 KSPROPERTY Property;
602 HRESULT hr;
603 ULONG BytesReturned;
604
605 Property.Set = KSPROPSETID_Connection;
606 Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
607 Property.Flags = KSPROPERTY_TYPE_SET;
608
609 hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
610 if (SUCCEEDED(hr))
611 {
612 pProps->cBuffers = Framing.Frames;
613 pProps->cbBuffer = Framing.FrameSize;
614 pProps->cbAlign = Framing.FileAlignment;
615 pProps->cbPrefix = 0;
616 return hr;
617 }
618 else
619 return E_NOTIMPL;
620 }
621
622 HRESULT
623 STDMETHODCALLTYPE
624 CInputPin::Receive(IMediaSample *pSample)
625 {
626 OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");
627 return E_NOTIMPL;
628 }
629
630 HRESULT
631 STDMETHODCALLTYPE
632 CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)
633 {
634 OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");
635 return E_NOTIMPL;
636 }
637
638 HRESULT
639 STDMETHODCALLTYPE
640 CInputPin::ReceiveCanBlock( void)
641 {
642 OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");
643 return S_FALSE;
644 }
645
646 //-------------------------------------------------------------------
647 // IKsPin
648 //
649
650 HRESULT
651 STDMETHODCALLTYPE
652 CInputPin::KsQueryMediums(
653 PKSMULTIPLE_ITEM* MediumList)
654 {
655 return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
656 }
657
658 HRESULT
659 STDMETHODCALLTYPE
660 CInputPin::KsQueryInterfaces(
661 PKSMULTIPLE_ITEM* InterfaceList)
662 {
663 return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
664 }
665
666 HRESULT
667 STDMETHODCALLTYPE
668 CInputPin::KsCreateSinkPinHandle(
669 KSPIN_INTERFACE& Interface,
670 KSPIN_MEDIUM& Medium)
671 {
672 OutputDebugStringW(L"CInputPin::KsCreateSinkPinHandle NotImplemented\n");
673 return E_NOTIMPL;
674 }
675
676 HRESULT
677 STDMETHODCALLTYPE
678 CInputPin::KsGetCurrentCommunication(
679 KSPIN_COMMUNICATION *Communication,
680 KSPIN_INTERFACE *Interface,
681 KSPIN_MEDIUM *Medium)
682 {
683 if (Communication)
684 {
685 *Communication = m_Communication;
686 }
687
688 if (Interface)
689 {
690 if (!m_hPin)
691 return VFW_E_NOT_CONNECTED;
692
693 CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE));
694 }
695
696 if (Medium)
697 {
698 if (!m_hPin)
699 return VFW_E_NOT_CONNECTED;
700
701 CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM));
702 }
703 return NOERROR;
704 }
705
706 HRESULT
707 STDMETHODCALLTYPE
708 CInputPin::KsPropagateAcquire()
709 {
710 OutputDebugStringW(L"CInputPin::KsPropagateAcquire NotImplemented\n");
711 return E_NOTIMPL;
712 }
713
714 HRESULT
715 STDMETHODCALLTYPE
716 CInputPin::KsDeliver(
717 IMediaSample* Sample,
718 ULONG Flags)
719 {
720 return E_FAIL;
721 }
722
723 HRESULT
724 STDMETHODCALLTYPE
725 CInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)
726 {
727 return NOERROR;
728 }
729
730 IMemAllocator *
731 STDMETHODCALLTYPE
732 CInputPin::KsPeekAllocator(KSPEEKOPERATION Operation)
733 {
734 if (Operation == KsPeekOperation_AddRef)
735 {
736 // add reference on allocator
737 m_MemAllocator->AddRef();
738 }
739
740 return m_MemAllocator;
741 }
742
743 HRESULT
744 STDMETHODCALLTYPE
745 CInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator)
746 {
747 if (MemAllocator)
748 {
749 MemAllocator->AddRef();
750 }
751
752 if (m_MemAllocator)
753 {
754 m_MemAllocator->Release();
755 }
756
757 m_MemAllocator = MemAllocator;
758 return NOERROR;
759 }
760
761 HRESULT
762 STDMETHODCALLTYPE
763 CInputPin::KsRenegotiateAllocator()
764 {
765 return E_FAIL;
766 }
767
768 LONG
769 STDMETHODCALLTYPE
770 CInputPin::KsIncrementPendingIoCount()
771 {
772 return InterlockedIncrement((volatile LONG*)&m_IoCount);
773 }
774
775 LONG
776 STDMETHODCALLTYPE
777 CInputPin::KsDecrementPendingIoCount()
778 {
779 return InterlockedDecrement((volatile LONG*)&m_IoCount);
780 }
781
782 HRESULT
783 STDMETHODCALLTYPE
784 CInputPin::KsQualityNotify(
785 ULONG Proportion,
786 REFERENCE_TIME TimeDelta)
787 {
788 OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");
789 return E_NOTIMPL;
790 }
791
792 //-------------------------------------------------------------------
793 // IKsPinEx
794 //
795
796 VOID
797 STDMETHODCALLTYPE
798 CInputPin::KsNotifyError(
799 IMediaSample* Sample,
800 HRESULT hr)
801 {
802 OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n");
803 }
804
805
806 //-------------------------------------------------------------------
807 // IKsControl
808 //
809 HRESULT
810 STDMETHODCALLTYPE
811 CInputPin::KsProperty(
812 PKSPROPERTY Property,
813 ULONG PropertyLength,
814 LPVOID PropertyData,
815 ULONG DataLength,
816 ULONG* BytesReturned)
817 {
818 assert(m_hPin != 0);
819 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
820 }
821
822 HRESULT
823 STDMETHODCALLTYPE
824 CInputPin::KsMethod(
825 PKSMETHOD Method,
826 ULONG MethodLength,
827 LPVOID MethodData,
828 ULONG DataLength,
829 ULONG* BytesReturned)
830 {
831 assert(m_hPin != 0);
832 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
833 }
834
835 HRESULT
836 STDMETHODCALLTYPE
837 CInputPin::KsEvent(
838 PKSEVENT Event,
839 ULONG EventLength,
840 LPVOID EventData,
841 ULONG DataLength,
842 ULONG* BytesReturned)
843 {
844 assert(m_hPin != 0);
845
846 if (EventLength)
847 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
848 else
849 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
850 }
851
852
853 //-------------------------------------------------------------------
854 // IKsPropertySet
855 //
856 HRESULT
857 STDMETHODCALLTYPE
858 CInputPin::Set(
859 REFGUID guidPropSet,
860 DWORD dwPropID,
861 LPVOID pInstanceData,
862 DWORD cbInstanceData,
863 LPVOID pPropData,
864 DWORD cbPropData)
865 {
866 ULONG BytesReturned;
867
868 if (cbInstanceData)
869 {
870 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
871 if (!Property)
872 return E_OUTOFMEMORY;
873
874 Property->Set = guidPropSet;
875 Property->Id = dwPropID;
876 Property->Flags = KSPROPERTY_TYPE_SET;
877
878 CopyMemory((Property+1), pInstanceData, cbInstanceData);
879
880 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
881 CoTaskMemFree(Property);
882 return hr;
883 }
884 else
885 {
886 KSPROPERTY Property;
887
888 Property.Set = guidPropSet;
889 Property.Id = dwPropID;
890 Property.Flags = KSPROPERTY_TYPE_SET;
891
892 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
893 return hr;
894 }
895 }
896
897 HRESULT
898 STDMETHODCALLTYPE
899 CInputPin::Get(
900 REFGUID guidPropSet,
901 DWORD dwPropID,
902 LPVOID pInstanceData,
903 DWORD cbInstanceData,
904 LPVOID pPropData,
905 DWORD cbPropData,
906 DWORD *pcbReturned)
907 {
908 ULONG BytesReturned;
909
910 if (cbInstanceData)
911 {
912 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
913 if (!Property)
914 return E_OUTOFMEMORY;
915
916 Property->Set = guidPropSet;
917 Property->Id = dwPropID;
918 Property->Flags = KSPROPERTY_TYPE_GET;
919
920 CopyMemory((Property+1), pInstanceData, cbInstanceData);
921
922 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
923 CoTaskMemFree(Property);
924 return hr;
925 }
926 else
927 {
928 KSPROPERTY Property;
929
930 Property.Set = guidPropSet;
931 Property.Id = dwPropID;
932 Property.Flags = KSPROPERTY_TYPE_GET;
933
934 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
935 return hr;
936 }
937 }
938
939 HRESULT
940 STDMETHODCALLTYPE
941 CInputPin::QuerySupported(
942 REFGUID guidPropSet,
943 DWORD dwPropID,
944 DWORD *pTypeSupport)
945 {
946 KSPROPERTY Property;
947 ULONG BytesReturned;
948
949 Property.Set = guidPropSet;
950 Property.Id = dwPropID;
951 Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
952
953 return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned);
954 }
955
956
957 //-------------------------------------------------------------------
958 // IKsObject
959 //
960 HANDLE
961 STDMETHODCALLTYPE
962 CInputPin::KsGetObjectHandle()
963 {
964 assert(m_hPin);
965 return m_hPin;
966 }
967
968 //-------------------------------------------------------------------
969 // IPin interface
970 //
971 HRESULT
972 STDMETHODCALLTYPE
973 CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
974 {
975 OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
976 return NOERROR;
977 }
978
979 HRESULT
980 STDMETHODCALLTYPE
981 CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
982 {
983 HRESULT hr;
984
985 if (m_Pin)
986 {
987 // already connected
988 return VFW_E_ALREADY_CONNECTED;
989 }
990
991 // first check format
992 hr = CheckFormat(pmt);
993 if (FAILED(hr))
994 {
995 // format is not supported
996 return hr;
997 }
998
999 hr = CreatePin(pmt);
1000 if (FAILED(hr))
1001 {
1002 return hr;
1003 }
1004
1005 m_Pin = pConnector;
1006 m_Pin->AddRef();
1007
1008 return S_OK;
1009 }
1010 HRESULT
1011 STDMETHODCALLTYPE
1012 CInputPin::Disconnect( void)
1013 {
1014 if (!m_Pin)
1015 {
1016 // pin was not connected
1017 return S_FALSE;
1018 }
1019
1020 //FIXME
1021 //check if filter is active
1022
1023 m_Pin->Release();
1024 m_Pin = NULL;
1025
1026 OutputDebugStringW(L"CInputPin::Disconnect\n");
1027 return S_OK;
1028 }
1029 HRESULT
1030 STDMETHODCALLTYPE
1031 CInputPin::ConnectedTo(IPin **pPin)
1032 {
1033 if (!pPin)
1034 return E_POINTER;
1035
1036 if (m_Pin)
1037 {
1038 // increment reference count
1039 m_Pin->AddRef();
1040 *pPin = m_Pin;
1041 return S_OK;
1042 }
1043
1044 *pPin = NULL;
1045 return VFW_E_NOT_CONNECTED;
1046 }
1047 HRESULT
1048 STDMETHODCALLTYPE
1049 CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
1050 {
1051 if (!m_Pin)
1052 return VFW_E_NOT_CONNECTED;
1053
1054 OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n");
1055 return E_NOTIMPL;
1056 }
1057 HRESULT
1058 STDMETHODCALLTYPE
1059 CInputPin::QueryPinInfo(PIN_INFO *pInfo)
1060 {
1061 wcscpy(pInfo->achName, m_PinName);
1062 pInfo->dir = PINDIR_INPUT;
1063 pInfo->pFilter = m_ParentFilter;
1064 m_ParentFilter->AddRef();
1065
1066 return S_OK;
1067 }
1068 HRESULT
1069 STDMETHODCALLTYPE
1070 CInputPin::QueryDirection(PIN_DIRECTION *pPinDir)
1071 {
1072 if (pPinDir)
1073 {
1074 *pPinDir = PINDIR_INPUT;
1075 return S_OK;
1076 }
1077
1078 return E_POINTER;
1079 }
1080 HRESULT
1081 STDMETHODCALLTYPE
1082 CInputPin::QueryId(LPWSTR *Id)
1083 {
1084 *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR));
1085 if (!*Id)
1086 return E_OUTOFMEMORY;
1087
1088 wcscpy(*Id, m_PinName);
1089 return S_OK;
1090 }
1091
1092 HRESULT
1093 STDMETHODCALLTYPE
1094 CInputPin::QueryAccept(
1095 const AM_MEDIA_TYPE *pmt)
1096 {
1097 return CheckFormat(pmt);
1098 }
1099 HRESULT
1100 STDMETHODCALLTYPE
1101 CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
1102 {
1103 HRESULT hr;
1104 ULONG MediaTypeCount = 0, Index;
1105 AM_MEDIA_TYPE * MediaTypes;
1106
1107 // query media type count
1108 hr = KsGetMediaTypeCount(m_hFilter, m_PinId, &MediaTypeCount);
1109 if (FAILED(hr) || !MediaTypeCount)
1110 return hr;
1111
1112 // allocate media types
1113 MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
1114 if (!MediaTypes)
1115 {
1116 // not enough memory
1117 return E_OUTOFMEMORY;
1118 }
1119
1120 // zero media types
1121 ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
1122
1123 for(Index = 0; Index < MediaTypeCount; Index++)
1124 {
1125 // get media type
1126 hr = KsGetMediaType(Index, &MediaTypes[Index], m_hFilter, m_PinId);
1127 if (FAILED(hr))
1128 {
1129 // failed
1130 CoTaskMemFree(MediaTypes);
1131 return hr;
1132 }
1133 }
1134
1135 return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);
1136 }
1137
1138 HRESULT
1139 STDMETHODCALLTYPE
1140 CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
1141 {
1142 OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
1143 return E_NOTIMPL;
1144 }
1145 HRESULT
1146 STDMETHODCALLTYPE
1147 CInputPin::EndOfStream( void)
1148 {
1149 OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
1150 return E_NOTIMPL;
1151 }
1152 HRESULT
1153 STDMETHODCALLTYPE
1154 CInputPin::BeginFlush( void)
1155 {
1156 OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
1157 return E_NOTIMPL;
1158 }
1159 HRESULT
1160 STDMETHODCALLTYPE
1161 CInputPin::EndFlush( void)
1162 {
1163 OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
1164 return E_NOTIMPL;
1165 }
1166 HRESULT
1167 STDMETHODCALLTYPE
1168 CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
1169 {
1170 OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
1171 return E_NOTIMPL;
1172 }
1173
1174
1175 //-------------------------------------------------------------------
1176 HRESULT
1177 STDMETHODCALLTYPE
1178 CInputPin::CheckFormat(
1179 const AM_MEDIA_TYPE *pmt)
1180 {
1181 KSP_PIN Property;
1182 PKSMULTIPLE_ITEM MultipleItem;
1183 PKSDATAFORMAT DataFormat;
1184 ULONG BytesReturned;
1185 HRESULT hr;
1186
1187 // prepare request
1188 Property.Property.Set = KSPROPSETID_Pin;
1189 Property.Property.Id = KSPROPERTY_PIN_DATARANGES;
1190 Property.Property.Flags = KSPROPERTY_TYPE_GET;
1191 Property.PinId = m_PinId;
1192 Property.Reserved = 0;
1193
1194 if (!pmt)
1195 return E_POINTER;
1196
1197 // query for size of dataranges
1198 hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
1199
1200 if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
1201 {
1202 // allocate dataranges buffer
1203 MultipleItem = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned);
1204
1205 if (!MultipleItem)
1206 return E_OUTOFMEMORY;
1207
1208 // query dataranges
1209 hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
1210
1211 if (FAILED(hr))
1212 {
1213 // failed to query data ranges
1214 CoTaskMemFree(MultipleItem);
1215 return hr;
1216 }
1217
1218 DataFormat = (PKSDATAFORMAT)(MultipleItem + 1);
1219 for(ULONG Index = 0; Index < MultipleItem->Count; Index++)
1220 {
1221 if (IsEqualGUID(pmt->majortype, DataFormat->MajorFormat) &&
1222 IsEqualGUID(pmt->subtype, DataFormat->SubFormat) &&
1223 IsEqualGUID(pmt->formattype, DataFormat->Specifier))
1224 {
1225 // format is supported
1226 CoTaskMemFree(MultipleItem);
1227 OutputDebugStringW(L"CInputPin::CheckFormat format OK\n");
1228 return S_OK;
1229 }
1230 DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize);
1231 }
1232 //format is not supported
1233 CoTaskMemFree(MultipleItem);
1234 }
1235 return S_FALSE;
1236 }
1237
1238 HRESULT
1239 STDMETHODCALLTYPE
1240 CInputPin::CreatePin(
1241 const AM_MEDIA_TYPE *pmt)
1242 {
1243 PKSMULTIPLE_ITEM MediumList;
1244 PKSMULTIPLE_ITEM InterfaceList;
1245 PKSPIN_MEDIUM Medium;
1246 PKSPIN_INTERFACE Interface;
1247 IKsInterfaceHandler * InterfaceHandler;
1248 HRESULT hr;
1249
1250 // query for pin medium
1251 hr = KsQueryMediums(&MediumList);
1252 if (FAILED(hr))
1253 return hr;
1254
1255 // query for pin interface
1256 hr = KsQueryInterfaces(&InterfaceList);
1257 if (FAILED(hr))
1258 {
1259 // failed
1260 CoTaskMemFree(MediumList);
1261 return hr;
1262 }
1263
1264 if (MediumList->Count)
1265 {
1266 //use first available medium
1267 Medium = (PKSPIN_MEDIUM)(MediumList + 1);
1268 }
1269 else
1270 {
1271 // default to standard medium
1272 Medium = &StandardPinMedium;
1273 }
1274
1275 if (InterfaceList->Count)
1276 {
1277 //use first available interface
1278 Interface = (PKSPIN_INTERFACE)(InterfaceList + 1);
1279 }
1280 else
1281 {
1282 // default to standard interface
1283 Interface = &StandardPinInterface;
1284 }
1285
1286 if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE)
1287 {
1288 // now load the IKsInterfaceHandler plugin
1289 hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler);
1290 if (FAILED(hr))
1291 {
1292 // failed to load interface handler plugin
1293 OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
1294 CoTaskMemFree(MediumList);
1295 CoTaskMemFree(InterfaceList);
1296
1297 return hr;
1298 }
1299
1300 // now set the pin
1301 hr = InterfaceHandler->KsSetPin((IKsPin*)this);
1302 if (FAILED(hr))
1303 {
1304 // failed to load interface handler plugin
1305 OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
1306 InterfaceHandler->Release();
1307 CoTaskMemFree(MediumList);
1308 CoTaskMemFree(InterfaceList);
1309 return hr;
1310 }
1311
1312 // store interface handler
1313 m_InterfaceHandler = InterfaceHandler;
1314
1315 // now create pin
1316 hr = CreatePinHandle(Medium, Interface, pmt);
1317 if (FAILED(hr))
1318 {
1319 m_InterfaceHandler->Release();
1320 m_InterfaceHandler = InterfaceHandler;
1321 }
1322 }
1323
1324 // free medium / interface / dataformat
1325 CoTaskMemFree(MediumList);
1326 CoTaskMemFree(InterfaceList);
1327
1328 return hr;
1329 }
1330
1331 HRESULT
1332 STDMETHODCALLTYPE
1333 CInputPin::CreatePinHandle(
1334 PKSPIN_MEDIUM Medium,
1335 PKSPIN_INTERFACE Interface,
1336 const AM_MEDIA_TYPE *pmt)
1337 {
1338 PKSPIN_CONNECT PinConnect;
1339 PKSDATAFORMAT DataFormat;
1340 ULONG Length;
1341 HRESULT hr;
1342
1343 // calc format size
1344 Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat;
1345
1346 // allocate pin connect
1347 PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length);
1348 if (!PinConnect)
1349 {
1350 // failed
1351 return E_OUTOFMEMORY;
1352 }
1353
1354 // setup request
1355 CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE));
1356 CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM));
1357 PinConnect->PinId = m_PinId;
1358 PinConnect->PinToHandle = NULL;
1359 PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
1360 PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
1361
1362 // get dataformat offset
1363 DataFormat = (PKSDATAFORMAT)(PinConnect + 1);
1364
1365 // copy data format
1366 DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat;
1367 DataFormat->Flags = 0;
1368 DataFormat->SampleSize = pmt->lSampleSize;
1369 DataFormat->Reserved = 0;
1370 CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID));
1371 CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID));
1372 CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID));
1373
1374 if (pmt->cbFormat)
1375 {
1376 // copy extended format
1377 CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat);
1378 }
1379
1380 // create pin
1381 hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
1382
1383 // free pin connect
1384 CoTaskMemFree(PinConnect);
1385
1386 return hr;
1387 }
1388
1389 HRESULT
1390 WINAPI
1391 CInputPin_Constructor(
1392 IBaseFilter * ParentFilter,
1393 LPCWSTR PinName,
1394 HANDLE hFilter,
1395 ULONG PinId,
1396 KSPIN_COMMUNICATION Communication,
1397 REFIID riid,
1398 LPVOID * ppv)
1399 {
1400 CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId, Communication);
1401
1402 if (!handler)
1403 return E_OUTOFMEMORY;
1404
1405 if (FAILED(handler->QueryInterface(riid, ppv)))
1406 {
1407 /* not supported */
1408 delete handler;
1409 return E_NOINTERFACE;
1410 }
1411
1412 return S_OK;
1413 }