xref: /reactos/dll/directx/msdvbnp/pin.cpp (revision c2c66aff)
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
12 const GUID KSDATAFORMAT_TYPE_BDA_ANTENNA = {0x71985f41, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
13 const GUID GUID_NULL                     = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
14 #endif
15 
16 class CPin : public IPin
17 {
18 public:
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 
59 protected:
60     LONG m_Ref;
61     IBaseFilter * m_ParentFilter;
62     AM_MEDIA_TYPE m_MediaType;
63     IPin * m_Pin;
64 };
65 
66 
67 LPCWSTR CPin::PIN_ID = L"Antenna Out";
68 
69 
70 CPin::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 
87 HRESULT
88 STDMETHODCALLTYPE
89 CPin::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 //
119 HRESULT
120 STDMETHODCALLTYPE
121 CPin::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 
161 HRESULT
162 STDMETHODCALLTYPE
163 CPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
164 {
165     return E_UNEXPECTED;
166 }
167 
168 HRESULT
169 STDMETHODCALLTYPE
170 CPin::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 }
187 HRESULT
188 STDMETHODCALLTYPE
189 CPin::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 }
209 HRESULT
210 STDMETHODCALLTYPE
211 CPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
212 {
213     OutputDebugStringW(L"CPin::ConnectionMediaType NotImplemented\n");
214     return E_NOTIMPL;
215 }
216 HRESULT
217 STDMETHODCALLTYPE
218 CPin::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 }
227 HRESULT
228 STDMETHODCALLTYPE
229 CPin::QueryDirection(PIN_DIRECTION *pPinDir)
230 {
231     if (pPinDir)
232     {
233         *pPinDir = PINDIR_OUTPUT;
234         return S_OK;
235     }
236 
237     return E_POINTER;
238 }
239 HRESULT
240 STDMETHODCALLTYPE
241 CPin::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 }
250 HRESULT
251 STDMETHODCALLTYPE
252 CPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
253 {
254     OutputDebugStringW(L"CPin::QueryAccept NotImplemented\n");
255     return E_NOTIMPL;
256 }
257 HRESULT
258 STDMETHODCALLTYPE
259 CPin::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 }
280 HRESULT
281 STDMETHODCALLTYPE
282 CPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
283 {
284     OutputDebugStringW(L"CPin::QueryInternalConnections NotImplemented\n");
285     return E_NOTIMPL;
286 }
287 HRESULT
288 STDMETHODCALLTYPE
289 CPin::EndOfStream( void)
290 {
291     OutputDebugStringW(L"CPin::EndOfStream NotImplemented\n");
292     return E_NOTIMPL;
293 }
294 HRESULT
295 STDMETHODCALLTYPE
296 CPin::BeginFlush( void)
297 {
298     OutputDebugStringW(L"CPin::BeginFlush NotImplemented\n");
299     return E_NOTIMPL;
300 }
301 HRESULT
302 STDMETHODCALLTYPE
303 CPin::EndFlush( void)
304 {
305     OutputDebugStringW(L"CPin::EndFlush NotImplemented\n");
306     return E_NOTIMPL;
307 }
308 HRESULT
309 STDMETHODCALLTYPE
310 CPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
311 {
312     OutputDebugStringW(L"CPin::NewSegment NotImplemented\n");
313     return E_NOTIMPL;
314 }
315 
316 HRESULT
317 WINAPI
318 CPin_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 }