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 }