5006b68a121522f666e954a9933999680b966481
[reactos.git] / reactos / 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 #endif
15 const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
16
17 class CKsDataTypeHandler : public IKsDataTypeHandler
18 {
19 public:
20 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
21
22 STDMETHODIMP_(ULONG) AddRef()
23 {
24 InterlockedIncrement(&m_Ref);
25 return m_Ref;
26 }
27 STDMETHODIMP_(ULONG) Release()
28 {
29 InterlockedDecrement(&m_Ref);
30
31 if (!m_Ref)
32 {
33 delete this;
34 return 0;
35 }
36 return m_Ref;
37 }
38
39 HRESULT STDMETHODCALLTYPE KsCompleteIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation, IN BOOL Cancelled);
40 HRESULT STDMETHODCALLTYPE KsIsMediaTypeInRanges(IN PVOID DataRanges);
41 HRESULT STDMETHODCALLTYPE KsPrepareIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation);
42 HRESULT STDMETHODCALLTYPE KsQueryExtendedSize(OUT ULONG* ExtendedSize);
43 HRESULT STDMETHODCALLTYPE KsSetMediaType(IN const AM_MEDIA_TYPE* AmMediaType);
44
45 CKsDataTypeHandler() : m_Ref(0), m_Type(0){};
46 virtual ~CKsDataTypeHandler()
47 {
48 if (m_Type)
49 {
50 if (m_Type->pbFormat)
51 CoTaskMemFree(m_Type->pbFormat);
52
53 if (m_Type->pUnk)
54 m_Type->pUnk->Release();
55
56 CoTaskMemFree(m_Type);
57 }
58
59 };
60
61 protected:
62 LONG m_Ref;
63 AM_MEDIA_TYPE * m_Type;
64 };
65
66
67 HRESULT
68 STDMETHODCALLTYPE
69 CKsDataTypeHandler::QueryInterface(
70 IN REFIID refiid,
71 OUT PVOID* Output)
72 {
73 if (IsEqualGUID(refiid, IID_IUnknown) ||
74 IsEqualGUID(refiid, IID_IKsDataTypeHandler))
75 {
76 *Output = PVOID(this);
77 reinterpret_cast<IUnknown*>(*Output)->AddRef();
78 return NOERROR;
79 }
80 return E_NOINTERFACE;
81 }
82
83
84 HRESULT
85 STDMETHODCALLTYPE
86 CKsDataTypeHandler::KsCompleteIoOperation(
87 IN OUT IMediaSample *Sample,
88 IN OUT PVOID StreamHeader,
89 IN KSIOOPERATION IoOperation,
90 IN BOOL Cancelled)
91 {
92 return NOERROR;
93 }
94
95
96 HRESULT
97 STDMETHODCALLTYPE
98 CKsDataTypeHandler::KsIsMediaTypeInRanges(
99 IN PVOID DataRanges)
100 {
101 PKSMULTIPLE_ITEM DataList;
102 PKSDATARANGE DataRange;
103 ULONG Index;
104 HRESULT hr = S_FALSE;
105
106 OutputDebugStringW(L"CKsDataTypeHandler::KsIsMediaTypeInRanges\n");
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 OutputDebugString("CKsDataTypeHandler::KsSetMediaType\n");
191
192 if (m_Type)
193 {
194 /* media type can only be set once */
195 return E_FAIL;
196 }
197
198 m_Type = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
199 if (!m_Type)
200 return E_OUTOFMEMORY;
201
202 CopyMemory(m_Type, AmMediaType, sizeof(AM_MEDIA_TYPE));
203
204 if (m_Type->cbFormat)
205 {
206 m_Type->pbFormat = (BYTE*)CoTaskMemAlloc(m_Type->cbFormat);
207
208 if (!m_Type->pbFormat)
209 {
210 CoTaskMemFree(m_Type);
211 return E_OUTOFMEMORY;
212 }
213
214 CopyMemory(m_Type->pbFormat, AmMediaType->pbFormat, m_Type->cbFormat);
215 }
216
217 if (m_Type->pUnk)
218 m_Type->pUnk->AddRef();
219
220
221 return S_OK;
222 }
223
224 HRESULT
225 WINAPI
226 CKsDataTypeHandler_Constructor (
227 IUnknown * pUnkOuter,
228 REFIID riid,
229 LPVOID * ppv)
230 {
231 OutputDebugStringW(L"CKsDataTypeHandler_Constructor\n");
232 CKsDataTypeHandler * handler = new CKsDataTypeHandler();
233
234 if (!handler)
235 return E_OUTOFMEMORY;
236
237 if (FAILED(handler->QueryInterface(riid, ppv)))
238 {
239 /* not supported */
240 delete handler;
241 return E_NOINTERFACE;
242 }
243
244 return NOERROR;
245 }