[KSPROXY]
[reactos.git] / reactos / dll / directx / ksproxy / output_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 #ifndef _MSC_VER
12 const GUID IID_IKsPinFactory = {0xCD5EBE6BL, 0x8B6E, 0x11D1, {0x8A, 0xE0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
13 #endif
14
15 class COutputPin : public IPin,
16 public IKsObject,
17 public IKsPropertySet,
18 public IStreamBuilder,
19 public IKsPinFactory,
20 public ISpecifyPropertyPages,
21 // public IKsPinPipe,
22 public IKsControl
23 /*
24 public IAMBufferNegotiation,
25 public IQualityControl,
26 public IKsPinEx,
27 public IKsAggregateControl
28 public IMediaSeeking,
29 public IAMStreamConfig,
30 public IMemAllocatorNotifyCallbackTemp
31 */
32 {
33 public:
34 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
35
36 STDMETHODIMP_(ULONG) AddRef()
37 {
38 InterlockedIncrement(&m_Ref);
39 return m_Ref;
40 }
41 STDMETHODIMP_(ULONG) Release()
42 {
43 InterlockedDecrement(&m_Ref);
44 if (!m_Ref)
45 {
46 //delete this;
47 return 0;
48 }
49 return m_Ref;
50 }
51
52 //IKsPinPipe
53 HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
54 HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
55 IPin* STDMETHODCALLTYPE KsGetConnectedPin();
56 IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation);
57 HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator);
58 ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag();
59 HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag);
60 GUID STDMETHODCALLTYPE KsGetPinBusCache();
61 HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus);
62 PWCHAR STDMETHODCALLTYPE KsGetPinName();
63 PWCHAR STDMETHODCALLTYPE KsGetFilterName();
64
65 //IPin methods
66 HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
67 HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
68 HRESULT STDMETHODCALLTYPE Disconnect();
69 HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin);
70 HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
71 HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
72 HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
73 HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
74 HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
75 HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
76 HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
77 HRESULT STDMETHODCALLTYPE EndOfStream();
78 HRESULT STDMETHODCALLTYPE BeginFlush();
79 HRESULT STDMETHODCALLTYPE EndFlush();
80 HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
81
82 // ISpecifyPropertyPages
83 HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
84
85 //IKsObject methods
86 HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
87
88 //IKsPropertySet
89 HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData);
90 HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned);
91 HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);
92
93 //IKsControl
94 HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
95 HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
96 HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
97
98 //IStreamBuilder
99 HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph);
100 HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
101
102 //IKsPinFactory
103 HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
104
105 COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId);
106 virtual ~COutputPin();
107
108 protected:
109 LONG m_Ref;
110 IBaseFilter * m_ParentFilter;
111 LPCWSTR m_PinName;
112 HANDLE m_hPin;
113 ULONG m_PinId;
114 IKsObject * m_KsObjectParent;
115 IPin * m_Pin;
116 };
117
118 COutputPin::~COutputPin()
119 {
120 if (m_KsObjectParent)
121 m_KsObjectParent->Release();
122 }
123
124 COutputPin::COutputPin(
125 IBaseFilter * ParentFilter,
126 LPCWSTR PinName,
127 ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(INVALID_HANDLE_VALUE), m_PinId(PinId), m_KsObjectParent(0), m_Pin(0)
128 {
129 HRESULT hr;
130
131 hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent);
132 assert(hr == S_OK);
133
134 };
135
136 HRESULT
137 STDMETHODCALLTYPE
138 COutputPin::QueryInterface(
139 IN REFIID refiid,
140 OUT PVOID* Output)
141 {
142 *Output = NULL;
143 if (IsEqualGUID(refiid, IID_IUnknown) ||
144 IsEqualGUID(refiid, IID_IPin))
145 {
146 OutputDebugStringW(L"COutputPin::QueryInterface IID_IPin\n");
147 *Output = PVOID(this);
148 reinterpret_cast<IUnknown*>(*Output)->AddRef();
149 return NOERROR;
150 }
151 else if (IsEqualGUID(refiid, IID_IKsObject))
152 {
153 OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsObject\n");
154 *Output = (IKsObject*)(this);
155 reinterpret_cast<IKsObject*>(*Output)->AddRef();
156 return NOERROR;
157 }
158 else if (IsEqualGUID(refiid, IID_IKsPropertySet))
159 {
160 OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPropertySet\n");
161 DebugBreak();
162 *Output = (IKsPropertySet*)(this);
163 reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
164 return NOERROR;
165 }
166 else if (IsEqualGUID(refiid, IID_IKsControl))
167 {
168 OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsControl\n");
169 *Output = (IKsControl*)(this);
170 reinterpret_cast<IKsControl*>(*Output)->AddRef();
171 return NOERROR;
172 }
173 #if 0
174 else if (IsEqualGUID(refiid, IID_IStreamBuilder))
175 {
176 *Output = (IStreamBuilder*)(this);
177 reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
178 return NOERROR;
179 }
180 #endif
181 else if (IsEqualGUID(refiid, IID_IKsPinFactory))
182 {
183 OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPinFactory\n");
184 *Output = (IKsPinFactory*)(this);
185 reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
186 return NOERROR;
187 }
188 else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
189 {
190 OutputDebugStringW(L"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
191 *Output = (ISpecifyPropertyPages*)(this);
192 reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
193 return NOERROR;
194 }
195
196 WCHAR Buffer[MAX_PATH];
197 LPOLESTR lpstr;
198 StringFromCLSID(refiid, &lpstr);
199 swprintf(Buffer, L"COutputPin::QueryInterface: NoInterface for %s\n", lpstr);
200 OutputDebugStringW(Buffer);
201 CoTaskMemFree(lpstr);
202
203 return E_NOINTERFACE;
204 }
205
206 //-------------------------------------------------------------------
207 // ISpecifyPropertyPages
208 //
209
210 HRESULT
211 STDMETHODCALLTYPE
212 COutputPin::GetPages(CAUUID *pPages)
213 {
214 OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n");
215
216 if (!pPages)
217 return E_POINTER;
218
219 pPages->cElems = 0;
220 pPages->pElems = NULL;
221
222 return S_OK;
223 }
224
225 //-------------------------------------------------------------------
226 // IKsPinFactory
227 //
228
229 HRESULT
230 STDMETHODCALLTYPE
231 COutputPin::KsPinFactory(
232 ULONG* PinFactory)
233 {
234 OutputDebugStringW(L"COutputPin::KsPinFactory\n");
235 *PinFactory = m_PinId;
236 return S_OK;
237 }
238
239
240 //-------------------------------------------------------------------
241 // IStreamBuilder
242 //
243
244 HRESULT
245 STDMETHODCALLTYPE
246 COutputPin::Render(
247 IPin *ppinOut,
248 IGraphBuilder *pGraph)
249 {
250 OutputDebugStringW(L"COutputPin::Render\n");
251 return S_OK;
252 }
253
254 HRESULT
255 STDMETHODCALLTYPE
256 COutputPin::Backout(
257 IPin *ppinOut,
258 IGraphBuilder *pGraph)
259 {
260 OutputDebugStringW(L"COutputPin::Backout\n");
261 return S_OK;
262 }
263 //-------------------------------------------------------------------
264 // IKsObject
265 //
266 HANDLE
267 STDMETHODCALLTYPE
268 COutputPin::KsGetObjectHandle()
269 {
270 OutputDebugStringW(L"COutputPin::KsGetObjectHandle\n");
271 assert(m_hPin);
272 return m_hPin;
273 }
274
275 //-------------------------------------------------------------------
276 // IKsControl
277 //
278 HRESULT
279 STDMETHODCALLTYPE
280 COutputPin::KsProperty(
281 PKSPROPERTY Property,
282 ULONG PropertyLength,
283 LPVOID PropertyData,
284 ULONG DataLength,
285 ULONG* BytesReturned)
286 {
287 assert(m_hPin != 0);
288 OutputDebugStringW(L"COutputPin::KsProperty\n");
289 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
290 }
291
292 HRESULT
293 STDMETHODCALLTYPE
294 COutputPin::KsMethod(
295 PKSMETHOD Method,
296 ULONG MethodLength,
297 LPVOID MethodData,
298 ULONG DataLength,
299 ULONG* BytesReturned)
300 {
301 assert(m_hPin != 0);
302 OutputDebugStringW(L"COutputPin::KsMethod\n");
303 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
304 }
305
306 HRESULT
307 STDMETHODCALLTYPE
308 COutputPin::KsEvent(
309 PKSEVENT Event,
310 ULONG EventLength,
311 LPVOID EventData,
312 ULONG DataLength,
313 ULONG* BytesReturned)
314 {
315 assert(m_hPin != 0);
316
317 OutputDebugStringW(L"COutputPin::KsEvent\n");
318
319 if (EventLength)
320 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
321 else
322 return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
323 }
324
325
326 //-------------------------------------------------------------------
327 // IKsPropertySet
328 //
329 HRESULT
330 STDMETHODCALLTYPE
331 COutputPin::Set(
332 REFGUID guidPropSet,
333 DWORD dwPropID,
334 LPVOID pInstanceData,
335 DWORD cbInstanceData,
336 LPVOID pPropData,
337 DWORD cbPropData)
338 {
339 ULONG BytesReturned;
340
341 OutputDebugStringW(L"COutputPin::Set\n");
342
343 if (cbInstanceData)
344 {
345 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
346 if (!Property)
347 return E_OUTOFMEMORY;
348
349 Property->Set = guidPropSet;
350 Property->Id = dwPropID;
351 Property->Flags = KSPROPERTY_TYPE_SET;
352
353 CopyMemory((Property+1), pInstanceData, cbInstanceData);
354
355 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
356 CoTaskMemFree(Property);
357 return hr;
358 }
359 else
360 {
361 KSPROPERTY Property;
362
363 Property.Set = guidPropSet;
364 Property.Id = dwPropID;
365 Property.Flags = KSPROPERTY_TYPE_SET;
366
367 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
368 return hr;
369 }
370 }
371
372 HRESULT
373 STDMETHODCALLTYPE
374 COutputPin::Get(
375 REFGUID guidPropSet,
376 DWORD dwPropID,
377 LPVOID pInstanceData,
378 DWORD cbInstanceData,
379 LPVOID pPropData,
380 DWORD cbPropData,
381 DWORD *pcbReturned)
382 {
383 ULONG BytesReturned;
384
385 OutputDebugStringW(L"COutputPin::Get\n");
386
387 if (cbInstanceData)
388 {
389 PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
390 if (!Property)
391 return E_OUTOFMEMORY;
392
393 Property->Set = guidPropSet;
394 Property->Id = dwPropID;
395 Property->Flags = KSPROPERTY_TYPE_GET;
396
397 CopyMemory((Property+1), pInstanceData, cbInstanceData);
398
399 HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
400 CoTaskMemFree(Property);
401 return hr;
402 }
403 else
404 {
405 KSPROPERTY Property;
406
407 Property.Set = guidPropSet;
408 Property.Id = dwPropID;
409 Property.Flags = KSPROPERTY_TYPE_GET;
410
411 HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
412 return hr;
413 }
414 }
415
416 HRESULT
417 STDMETHODCALLTYPE
418 COutputPin::QuerySupported(
419 REFGUID guidPropSet,
420 DWORD dwPropID,
421 DWORD *pTypeSupport)
422 {
423 KSPROPERTY Property;
424 ULONG BytesReturned;
425
426 OutputDebugStringW(L"COutputPin::QuerySupported\n");
427
428 Property.Set = guidPropSet;
429 Property.Id = dwPropID;
430 Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
431
432 return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned);
433 }
434
435
436 //-------------------------------------------------------------------
437 // IPin interface
438 //
439 HRESULT
440 STDMETHODCALLTYPE
441 COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
442 {
443 AM_MEDIA_TYPE MediaType;
444 HRESULT hr;
445 HANDLE hFilter;
446
447 OutputDebugStringW(L"COutputPin::Connect called\n");
448 if (pmt)
449 {
450 hr = pReceivePin->QueryAccept(pmt);
451 if (FAILED(hr))
452 return hr;
453 }
454 else
455 {
456 // get parent filter handle
457 hFilter = m_KsObjectParent->KsGetObjectHandle();
458
459 // get media type count
460 ZeroMemory(&MediaType, sizeof(AM_MEDIA_TYPE));
461 hr = KsGetMediaType(0, &MediaType, hFilter, m_PinId);
462 if (FAILED(hr))
463 return hr;
464
465 // query accept
466 hr = pReceivePin->QueryAccept(&MediaType);
467 if (FAILED(hr))
468 return hr;
469
470 pmt = &MediaType;
471 }
472
473 //FIXME create pin handle
474
475 // receive connection;
476 hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
477 if (SUCCEEDED(hr))
478 {
479 // increment reference count
480 pReceivePin->AddRef();
481 m_Pin = pReceivePin;
482 OutputDebugStringW(L"COutputPin::Connect success\n");
483 }
484
485 return hr;
486 }
487
488 HRESULT
489 STDMETHODCALLTYPE
490 COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
491 {
492 OutputDebugStringW(L"COutputPin::ReceiveConnection\n");
493 return E_UNEXPECTED;
494 }
495 HRESULT
496 STDMETHODCALLTYPE
497 COutputPin::Disconnect( void)
498 {
499 OutputDebugStringW(L"COutputPin::Disconnect\n");
500
501 if (!m_Pin)
502 {
503 // pin was not connected
504 return S_FALSE;
505 }
506
507 //FIXME
508 //check if filter is active
509
510 m_Pin->Release();
511 m_Pin = NULL;
512
513 OutputDebugStringW(L"COutputPin::Disconnect\n");
514 return S_OK;
515 }
516 HRESULT
517 STDMETHODCALLTYPE
518 COutputPin::ConnectedTo(IPin **pPin)
519 {
520 OutputDebugStringW(L"COutputPin::ConnectedTo\n");
521
522 if (!pPin)
523 return E_POINTER;
524
525 if (m_Pin)
526 {
527 // increment reference count
528 m_Pin->AddRef();
529 *pPin = m_Pin;
530 return S_OK;
531 }
532
533 *pPin = NULL;
534 return VFW_E_NOT_CONNECTED;
535 }
536 HRESULT
537 STDMETHODCALLTYPE
538 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
539 {
540 OutputDebugStringW(L"COutputPin::ConnectionMediaType called\n");
541 return E_NOTIMPL;
542 }
543 HRESULT
544 STDMETHODCALLTYPE
545 COutputPin::QueryPinInfo(PIN_INFO *pInfo)
546 {
547 OutputDebugStringW(L"COutputPin::QueryPinInfo\n");
548
549 wcscpy(pInfo->achName, m_PinName);
550 pInfo->dir = PINDIR_OUTPUT;
551 pInfo->pFilter = m_ParentFilter;
552 m_ParentFilter->AddRef();
553
554 return S_OK;
555 }
556 HRESULT
557 STDMETHODCALLTYPE
558 COutputPin::QueryDirection(PIN_DIRECTION *pPinDir)
559 {
560 OutputDebugStringW(L"COutputPin::QueryDirection\n");
561
562 if (pPinDir)
563 {
564 *pPinDir = PINDIR_OUTPUT;
565 return S_OK;
566 }
567
568 return E_POINTER;
569 }
570 HRESULT
571 STDMETHODCALLTYPE
572 COutputPin::QueryId(LPWSTR *Id)
573 {
574 OutputDebugStringW(L"COutputPin::QueryId\n");
575
576 *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR));
577 if (!*Id)
578 return E_OUTOFMEMORY;
579
580 wcscpy(*Id, m_PinName);
581 return S_OK;
582 }
583 HRESULT
584 STDMETHODCALLTYPE
585 COutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
586 {
587 OutputDebugStringW(L"COutputPin::QueryAccept called\n");
588 return E_NOTIMPL;
589 }
590 HRESULT
591 STDMETHODCALLTYPE
592 COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
593 {
594 HRESULT hr;
595 ULONG MediaTypeCount = 0, Index;
596 AM_MEDIA_TYPE * MediaTypes;
597 HANDLE hFilter;
598
599 OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n");
600
601 if (!m_KsObjectParent)
602 {
603 // no interface
604 return E_NOINTERFACE;
605 }
606
607 // get parent filter handle
608 hFilter = m_KsObjectParent->KsGetObjectHandle();
609
610 // query media type count
611 hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
612 if (FAILED(hr) || !MediaTypeCount)
613 {
614 OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n");
615 return hr;
616 }
617
618 // allocate media types
619 MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
620 if (!MediaTypes)
621 {
622 // not enough memory
623 OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n");
624 return E_OUTOFMEMORY;
625 }
626
627 // zero media types
628 ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
629
630 for(Index = 0; Index < MediaTypeCount; Index++)
631 {
632 // get media type
633 hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId);
634 if (FAILED(hr))
635 {
636 // failed
637 CoTaskMemFree(MediaTypes);
638 OutputDebugStringW(L"COutputPin::EnumMediaTypes failed\n");
639 return hr;
640 }
641 }
642
643 return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);
644 }
645 HRESULT
646 STDMETHODCALLTYPE
647 COutputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
648 {
649 OutputDebugStringW(L"COutputPin::QueryInternalConnections called\n");
650 return E_NOTIMPL;
651 }
652 HRESULT
653 STDMETHODCALLTYPE
654 COutputPin::EndOfStream( void)
655 {
656 OutputDebugStringW(L"COutputPin::EndOfStream called\n");
657 return E_NOTIMPL;
658 }
659 HRESULT
660 STDMETHODCALLTYPE
661 COutputPin::BeginFlush( void)
662 {
663 OutputDebugStringW(L"COutputPin::BeginFlush called\n");
664 return E_NOTIMPL;
665 }
666 HRESULT
667 STDMETHODCALLTYPE
668 COutputPin::EndFlush( void)
669 {
670 OutputDebugStringW(L"COutputPin::EndFlush called\n");
671 return E_NOTIMPL;
672 }
673 HRESULT
674 STDMETHODCALLTYPE
675 COutputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
676 {
677 OutputDebugStringW(L"COutputPin::NewSegment called\n");
678 return E_NOTIMPL;
679 }
680
681 HRESULT
682 WINAPI
683 COutputPin_Constructor(
684 IBaseFilter * ParentFilter,
685 LPCWSTR PinName,
686 ULONG PinId,
687 REFIID riid,
688 LPVOID * ppv)
689 {
690 COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId);
691
692 if (!handler)
693 return E_OUTOFMEMORY;
694
695 if (FAILED(handler->QueryInterface(riid, ppv)))
696 {
697 /* not supported */
698 delete handler;
699 return E_NOINTERFACE;
700 }
701
702 return S_OK;
703 }