1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy 4 * FILE: dll/directx/ksproxy/datatype.cpp 5 * PURPOSE: IKsDataTypeHandler interface 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 #include "precomp.h" 10 11 /* FIXME guid mess */ 12 const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; 13 const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; 14 15 class CKsDataTypeHandler : public IKsDataTypeHandler 16 { 17 public: 18 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 19 20 STDMETHODIMP_(ULONG) AddRef() 21 { 22 InterlockedIncrement(&m_Ref); 23 return m_Ref; 24 } 25 STDMETHODIMP_(ULONG) Release() 26 { 27 InterlockedDecrement(&m_Ref); 28 29 if (!m_Ref) 30 { 31 delete this; 32 return 0; 33 } 34 return m_Ref; 35 } 36 37 HRESULT STDMETHODCALLTYPE KsCompleteIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation, IN BOOL Cancelled); 38 HRESULT STDMETHODCALLTYPE KsIsMediaTypeInRanges(IN PVOID DataRanges); 39 HRESULT STDMETHODCALLTYPE KsPrepareIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation); 40 HRESULT STDMETHODCALLTYPE KsQueryExtendedSize(OUT ULONG* ExtendedSize); 41 HRESULT STDMETHODCALLTYPE KsSetMediaType(IN const AM_MEDIA_TYPE* AmMediaType); 42 43 CKsDataTypeHandler() : m_Ref(0), m_Type(0){}; 44 virtual ~CKsDataTypeHandler() 45 { 46 if (m_Type) 47 { 48 if (m_Type->pbFormat) 49 CoTaskMemFree(m_Type->pbFormat); 50 51 if (m_Type->pUnk) 52 m_Type->pUnk->Release(); 53 54 CoTaskMemFree(m_Type); 55 } 56 57 }; 58 59 protected: 60 LONG m_Ref; 61 AM_MEDIA_TYPE * m_Type; 62 }; 63 64 65 HRESULT 66 STDMETHODCALLTYPE 67 CKsDataTypeHandler::QueryInterface( 68 IN REFIID refiid, 69 OUT PVOID* Output) 70 { 71 if (IsEqualGUID(refiid, IID_IUnknown) || 72 IsEqualGUID(refiid, IID_IKsDataTypeHandler)) 73 { 74 *Output = PVOID(this); 75 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 76 return NOERROR; 77 } 78 return E_NOINTERFACE; 79 } 80 81 82 HRESULT 83 STDMETHODCALLTYPE 84 CKsDataTypeHandler::KsCompleteIoOperation( 85 IN OUT IMediaSample *Sample, 86 IN OUT PVOID StreamHeader, 87 IN KSIOOPERATION IoOperation, 88 IN BOOL Cancelled) 89 { 90 return NOERROR; 91 } 92 93 94 HRESULT 95 STDMETHODCALLTYPE 96 CKsDataTypeHandler::KsIsMediaTypeInRanges( 97 IN PVOID DataRanges) 98 { 99 PKSMULTIPLE_ITEM DataList; 100 PKSDATARANGE DataRange; 101 ULONG Index; 102 //HRESULT hr = S_FALSE; 103 104 #ifdef KSPROXY_TRACE 105 OutputDebugStringW(L"CKsDataTypeHandler::KsIsMediaTypeInRanges\n"); 106 #endif 107 108 DataList = (PKSMULTIPLE_ITEM)DataRanges; 109 DataRange = (PKSDATARANGE)(DataList + 1); 110 111 for(Index = 0; Index < DataList->Count; Index++) 112 { 113 BOOL bMatch = FALSE; 114 115 if (DataRange->FormatSize >= sizeof(KSDATARANGE)) 116 { 117 bMatch = IsEqualGUID(DataRange->MajorFormat, GUID_NULL); 118 } 119 120 if (!bMatch && DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO)) 121 { 122 bMatch = IsEqualGUID(DataRange->MajorFormat, MEDIATYPE_Audio); 123 } 124 125 if (bMatch) 126 { 127 if (IsEqualGUID(DataRange->SubFormat, m_Type->subtype) || 128 IsEqualGUID(DataRange->SubFormat, GUID_NULL)) 129 { 130 if (IsEqualGUID(DataRange->Specifier, m_Type->formattype) || 131 IsEqualGUID(DataRange->Specifier, GUID_NULL)) 132 { 133 if (!IsEqualGUID(m_Type->formattype, FORMAT_WaveFormatEx) && !IsEqualGUID(DataRange->Specifier, FORMAT_WaveFormatEx)) 134 { 135 //found match 136 //hr = S_OK; 137 break; 138 } 139 140 if (DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO) && m_Type->cbFormat >= sizeof(WAVEFORMATEX)) 141 { 142 LPWAVEFORMATEX Format = (LPWAVEFORMATEX)m_Type->pbFormat; 143 PKSDATARANGE_AUDIO AudioRange = (PKSDATARANGE_AUDIO)DataRange; 144 145 if (Format->nSamplesPerSec >= AudioRange->MinimumSampleFrequency && 146 Format->nSamplesPerSec <= AudioRange->MaximumSampleFrequency && 147 Format->wBitsPerSample >= AudioRange->MinimumSampleFrequency && 148 Format->wBitsPerSample <= AudioRange->MaximumBitsPerSample && 149 Format->nChannels <= AudioRange->MaximumChannels) 150 { 151 // found match 152 //hr = S_OK; 153 break; 154 } 155 } 156 } 157 } 158 } 159 160 DataRange = (PKSDATARANGE)(((ULONG_PTR)DataRange + DataRange->FormatSize + 7) & ~7); 161 } 162 return S_OK; 163 } 164 165 HRESULT 166 STDMETHODCALLTYPE 167 CKsDataTypeHandler::KsPrepareIoOperation( 168 IN OUT IMediaSample *Sample, 169 IN OUT PVOID StreamHeader, 170 IN KSIOOPERATION IoOperation) 171 { 172 return NOERROR; 173 } 174 175 HRESULT 176 STDMETHODCALLTYPE 177 CKsDataTypeHandler::KsQueryExtendedSize( 178 OUT ULONG* ExtendedSize) 179 { 180 /* no header extension required */ 181 *ExtendedSize = 0; 182 return NOERROR; 183 } 184 185 HRESULT 186 STDMETHODCALLTYPE 187 CKsDataTypeHandler::KsSetMediaType( 188 IN const AM_MEDIA_TYPE* AmMediaType) 189 { 190 #ifdef KSPROXY_TRACE 191 OutputDebugString("CKsDataTypeHandler::KsSetMediaType\n"); 192 #endif 193 194 if (m_Type) 195 { 196 /* media type can only be set once */ 197 return E_FAIL; 198 } 199 200 m_Type = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); 201 if (!m_Type) 202 return E_OUTOFMEMORY; 203 204 CopyMemory(m_Type, AmMediaType, sizeof(AM_MEDIA_TYPE)); 205 206 if (m_Type->cbFormat) 207 { 208 m_Type->pbFormat = (BYTE*)CoTaskMemAlloc(m_Type->cbFormat); 209 210 if (!m_Type->pbFormat) 211 { 212 CoTaskMemFree(m_Type); 213 return E_OUTOFMEMORY; 214 } 215 216 CopyMemory(m_Type->pbFormat, AmMediaType->pbFormat, m_Type->cbFormat); 217 } 218 219 if (m_Type->pUnk) 220 m_Type->pUnk->AddRef(); 221 222 223 return S_OK; 224 } 225 226 HRESULT 227 WINAPI 228 CKsDataTypeHandler_Constructor ( 229 IUnknown * pUnkOuter, 230 REFIID riid, 231 LPVOID * ppv) 232 { 233 #ifdef KSPROXY_TRACE 234 OutputDebugStringW(L"CKsDataTypeHandler_Constructor\n"); 235 #endif 236 237 CKsDataTypeHandler * handler = new CKsDataTypeHandler(); 238 239 if (!handler) 240 return E_OUTOFMEMORY; 241 242 if (FAILED(handler->QueryInterface(riid, ppv))) 243 { 244 /* not supported */ 245 delete handler; 246 return E_NOINTERFACE; 247 } 248 249 return NOERROR; 250 } 251