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