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
AddRef()20 STDMETHODIMP_(ULONG) AddRef()
21 {
22 InterlockedIncrement(&m_Ref);
23 return m_Ref;
24 }
Release()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
CKsDataTypeHandler()43 CKsDataTypeHandler() : m_Ref(0), m_Type(0){};
~CKsDataTypeHandler()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
QueryInterface(IN REFIID refiid,OUT PVOID * Output)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
KsCompleteIoOperation(IN OUT IMediaSample * Sample,IN OUT PVOID StreamHeader,IN KSIOOPERATION IoOperation,IN BOOL Cancelled)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
KsIsMediaTypeInRanges(IN PVOID DataRanges)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
KsPrepareIoOperation(IN OUT IMediaSample * Sample,IN OUT PVOID StreamHeader,IN KSIOOPERATION IoOperation)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
KsQueryExtendedSize(OUT ULONG * ExtendedSize)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
KsSetMediaType(IN const AM_MEDIA_TYPE * AmMediaType)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
CKsDataTypeHandler_Constructor(IUnknown * pUnkOuter,REFIID riid,LPVOID * ppv)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