Reactos
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Network Provider for MPEG2 based networks
4 * FILE: dll/directx/msdvbnp/pin.cpp
5 * PURPOSE: IPin interface
6 *
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9#include "precomp.h"
10
11#ifndef _MSC_VER
12const GUID KSDATAFORMAT_TYPE_BDA_ANTENNA = {0x71985f41, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
13const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
14#endif
15
16class CPin : public IPin
17{
18public:
19 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
20
21 STDMETHODIMP_(ULONG) AddRef()
22 {
23 InterlockedIncrement(&m_Ref);
24 return m_Ref;
25 }
26 STDMETHODIMP_(ULONG) Release()
27 {
28 InterlockedDecrement(&m_Ref);
29 if (!m_Ref)
30 {
31 delete this;
32 return 0;
33 }
34 return m_Ref;
35 }
36
37 //IPin methods
38 HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
39 HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
40 HRESULT STDMETHODCALLTYPE Disconnect();
41 HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin);
42 HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
43 HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
44 HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
45 HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
46 HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
47 HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
48 HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
49 HRESULT STDMETHODCALLTYPE EndOfStream();
50 HRESULT STDMETHODCALLTYPE BeginFlush();
51 HRESULT STDMETHODCALLTYPE EndFlush();
52 HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
53
54 CPin(IBaseFilter * ParentFilter);
55 virtual ~CPin(){};
56
57 static LPCWSTR PIN_ID;
58
59protected:
60 LONG m_Ref;
61 IBaseFilter * m_ParentFilter;
62 AM_MEDIA_TYPE m_MediaType;
63 IPin * m_Pin;
64};
65
66
67LPCWSTR CPin::PIN_ID = L"Antenna Out";
68
69
70CPin::CPin(
71 IBaseFilter * ParentFilter) : m_Ref(0),
72 m_ParentFilter(ParentFilter),
73 m_Pin(0)
74{
75 m_MediaType.majortype = KSDATAFORMAT_TYPE_BDA_ANTENNA;
76 m_MediaType.subtype = MEDIASUBTYPE_None;
77 m_MediaType.formattype = FORMAT_None;
78 m_MediaType.bFixedSizeSamples = true;
79 m_MediaType.bTemporalCompression = false;
80 m_MediaType.lSampleSize = sizeof(CHAR);
81 m_MediaType.pUnk = NULL;
82 m_MediaType.cbFormat = 0;
83 m_MediaType.pbFormat = NULL;
84}
85
86
87HRESULT
88STDMETHODCALLTYPE
89CPin::QueryInterface(
90 IN REFIID refiid,
91 OUT PVOID* Output)
92{
93 if (IsEqualGUID(refiid, IID_IUnknown))
94 {
95 *Output = PVOID(this);
96 reinterpret_cast<IUnknown*>(*Output)->AddRef();
97 return NOERROR;
98 }
99 if (IsEqualGUID(refiid, IID_IPin))
100 {
101 *Output = (IPin*)(this);
102 reinterpret_cast<IPin*>(*Output)->AddRef();
103 return NOERROR;
104 }
105
106 WCHAR Buffer[MAX_PATH];
107 LPOLESTR lpstr;
108 StringFromCLSID(refiid, &lpstr);
109 swprintf(Buffer, L"CPin::QueryInterface: NoInterface for %s\n", lpstr);
110 OutputDebugStringW(Buffer);
111 CoTaskMemFree(lpstr);
112
113 return E_NOINTERFACE;
114}
115
116//-------------------------------------------------------------------
117// IPin interface
118//
119HRESULT
120STDMETHODCALLTYPE
121CPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
122{
123 HRESULT hr;
124 OutputDebugStringW(L"CPin::Connect called\n");
125
126 if (pmt)
127 {
128 hr = pReceivePin->QueryAccept(pmt);
129 if (FAILED(hr))
130 {
131 OutputDebugStringW(L"CPin::Connect QueryAccept failed\n");
132 return hr;
133 }
134 }
135 else
136 {
137 // query accept
138 hr = pReceivePin->QueryAccept(&m_MediaType);
139 if (FAILED(hr))
140 {
141 OutputDebugStringW(L"CPin::Connect QueryAccept pmt default failed\n");
142 return hr;
143 }
144
145 pmt = &m_MediaType;
146 }
147
148 // receive connection;
149 hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
150 if (SUCCEEDED(hr))
151 {
152 // increment reference count
153 pReceivePin->AddRef();
154 m_Pin = pReceivePin;
155 OutputDebugStringW(L"CPin::Connect success\n");
156 }
157
158 return hr;
159}
160
161HRESULT
162STDMETHODCALLTYPE
163CPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
164{
165 return E_UNEXPECTED;
166}
167
168HRESULT
169STDMETHODCALLTYPE
170CPin::Disconnect( void)
171{
172#ifdef MSDVBNP_TRACE
173 OutputDebugStringW(L"CPin::Disconnect\n");
174#endif
175
176 if (!m_Pin)
177 {
178 // pin was not connected
179 return S_FALSE;
180 }
181
182 m_Pin->Release();
183 m_Pin = NULL;
184
185 return S_OK;
186}
187HRESULT
188STDMETHODCALLTYPE
189CPin::ConnectedTo(IPin **pPin)
190{
191#ifdef MSDVBNP_TRACE
192 OutputDebugStringW(L"CPin::ConnectedTo\n");
193#endif
194
195 if (!pPin)
196 return E_POINTER;
197
198 if (m_Pin)
199 {
200 // increment reference count
201 m_Pin->AddRef();
202 *pPin = m_Pin;
203 return S_OK;
204 }
205
206 *pPin = NULL;
207 return VFW_E_NOT_CONNECTED;
208}
209HRESULT
210STDMETHODCALLTYPE
211CPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
212{
213 OutputDebugStringW(L"CPin::ConnectionMediaType NotImplemented\n");
214 return E_NOTIMPL;
215}
216HRESULT
217STDMETHODCALLTYPE
218CPin::QueryPinInfo(PIN_INFO *pInfo)
219{
220 wcscpy(pInfo->achName, PIN_ID);
221 pInfo->dir = PINDIR_OUTPUT;
222 pInfo->pFilter = m_ParentFilter;
223 m_ParentFilter->AddRef();
224
225 return S_OK;
226}
227HRESULT
228STDMETHODCALLTYPE
229CPin::QueryDirection(PIN_DIRECTION *pPinDir)
230{
231 if (pPinDir)
232 {
233 *pPinDir = PINDIR_OUTPUT;
234 return S_OK;
235 }
236
237 return E_POINTER;
238}
239HRESULT
240STDMETHODCALLTYPE
241CPin::QueryId(LPWSTR *Id)
242{
243 *Id = (LPWSTR)CoTaskMemAlloc(sizeof(PIN_ID));
244 if (!*Id)
245 return E_OUTOFMEMORY;
246
247 wcscpy(*Id, PIN_ID);
248 return S_OK;
249}
250HRESULT
251STDMETHODCALLTYPE
252CPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
253{
254 OutputDebugStringW(L"CPin::QueryAccept NotImplemented\n");
255 return E_NOTIMPL;
256}
257HRESULT
258STDMETHODCALLTYPE
259CPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
260{
261 AM_MEDIA_TYPE *MediaType = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
262
263 if (!MediaType)
264 {
265 return E_OUTOFMEMORY;
266 }
267
268 MediaType->majortype = KSDATAFORMAT_TYPE_BDA_ANTENNA;
269 MediaType->subtype = MEDIASUBTYPE_None;
270 MediaType->formattype = FORMAT_None;
271 MediaType->bFixedSizeSamples = true;
272 MediaType->bTemporalCompression = false;
273 MediaType->lSampleSize = sizeof(CHAR);
274 MediaType->pUnk = NULL;
275 MediaType->cbFormat = 0;
276 MediaType->pbFormat = NULL;
277
278 return CEnumMediaTypes_fnConstructor(NULL, 1, MediaType, IID_IEnumMediaTypes, (void**)ppEnum);
279}
280HRESULT
281STDMETHODCALLTYPE
282CPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
283{
284 OutputDebugStringW(L"CPin::QueryInternalConnections NotImplemented\n");
285 return E_NOTIMPL;
286}
287HRESULT
288STDMETHODCALLTYPE
289CPin::EndOfStream( void)
290{
291 OutputDebugStringW(L"CPin::EndOfStream NotImplemented\n");
292 return E_NOTIMPL;
293}
294HRESULT
295STDMETHODCALLTYPE
296CPin::BeginFlush( void)
297{
298 OutputDebugStringW(L"CPin::BeginFlush NotImplemented\n");
299 return E_NOTIMPL;
300}
301HRESULT
302STDMETHODCALLTYPE
303CPin::EndFlush( void)
304{
305 OutputDebugStringW(L"CPin::EndFlush NotImplemented\n");
306 return E_NOTIMPL;
307}
308HRESULT
309STDMETHODCALLTYPE
310CPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
311{
312 OutputDebugStringW(L"CPin::NewSegment NotImplemented\n");
313 return E_NOTIMPL;
314}
315
316HRESULT
317WINAPI
318CPin_fnConstructor(
319 IUnknown *pUnknown,
320 IBaseFilter * ParentFilter,
321 REFIID riid,
322 LPVOID * ppv)
323{
324 CPin * handler = new CPin(ParentFilter);
325
326#ifdef MSDVBNP_TRACE
327 WCHAR Buffer[MAX_PATH];
328 LPOLESTR lpstr;
329 StringFromCLSID(riid, &lpstr);
330 swprintf(Buffer, L"CPin_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
331 OutputDebugStringW(Buffer);
332#endif
333
334 if (!handler)
335 return E_OUTOFMEMORY;
336
337 if (FAILED(handler->QueryInterface(riid, ppv)))
338 {
339 /* not supported */
340 delete handler;
341 return E_NOINTERFACE;
342 }
343
344 return NOERROR;
345}