1 #include <assert.h>
2
3 // Helper class to implement IMFAttributes.
4
5 // This is an abstract class; the derived class must implement the IUnknown
6 // methods. This class is a wrapper for the standard attribute store provided
7 // in Media Foundation.
8
9 // template parameter:
10 // The interface you are implementing, either IMFAttributes or an interface
11 // that inherits IMFAttributes, such as IMFActivate
12
13 template <class IFACE=IMFAttributes>
14 class CBaseAttributes : public IFACE
15 {
16 protected:
17 IMFAttributes *m_pAttributes;
18
19 // This version of the constructor does not initialize the
20 // attribute store. The derived class must call Initialize() in
21 // its own constructor.
22 CBaseAttributes() : m_pAttributes(NULL)
23 {
24 }
25
26 // This version of the constructor initializes the attribute
27 // store, but the derived class must pass an HRESULT parameter
28 // to the constructor.
29
30 CBaseAttributes(HRESULT& hr, UINT32 cInitialSize = 0) : m_pAttributes(NULL)
31 {
32 hr = Initialize(cInitialSize);
33 }
34
35 // The next version of the constructor uses a caller-provided
36 // implementation of IMFAttributes.
37
38 // (Sometimes you want to delegate IMFAttributes calls to some
39 // other object that implements IMFAttributes, rather than using
40 // MFCreateAttributes.)
41
42 CBaseAttributes(HRESULT& hr, IUnknown *pUnk)
43 {
44 hr = Initialize(pUnk);
45 }
46
47 virtual ~CBaseAttributes()
48 {
49 if (m_pAttributes)
50 {
51 m_pAttributes->Release();
52 }
53 }
54
55 // Initializes the object by creating the standard Media Foundation attribute store.
56 HRESULT Initialize(UINT32 cInitialSize = 0)
57 {
58 if (m_pAttributes == NULL)
59 {
60 return MFCreateAttributes(&m_pAttributes, cInitialSize);
61 }
62 else
63 {
64 return S_OK;
65 }
66 }
67
68 // Initializes this object from a caller-provided attribute store.
69 // pUnk: Pointer to an object that exposes IMFAttributes.
70 HRESULT Initialize(IUnknown *pUnk)
71 {
72 if (m_pAttributes)
73 {
74 m_pAttributes->Release();
75 m_pAttributes = NULL;
76 }
77
78
79 return pUnk->QueryInterface(IID_PPV_ARGS(&m_pAttributes));
80 }
81
82 public:
83
84 // IMFAttributes methods
85
86 STDMETHODIMP GetItem(REFGUID guidKey, PROPVARIANT* pValue)
87 {
88 assert(m_pAttributes);
89 return m_pAttributes->GetItem(guidKey, pValue);
90 }
91
92 STDMETHODIMP GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType)
93 {
94 assert(m_pAttributes);
95 return m_pAttributes->GetItemType(guidKey, pType);
96 }
97
98 STDMETHODIMP CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult)
99 {
100 assert(m_pAttributes);
101 return m_pAttributes->CompareItem(guidKey, Value, pbResult);
102 }
103
104 STDMETHODIMP Compare(
105 IMFAttributes* pTheirs,
106 MF_ATTRIBUTES_MATCH_TYPE MatchType,
107 BOOL* pbResult
108 )
109 {
110 assert(m_pAttributes);
111 return m_pAttributes->Compare(pTheirs, MatchType, pbResult);
112 }
113
114 STDMETHODIMP GetUINT32(REFGUID guidKey, UINT32* punValue)
115 {
116 assert(m_pAttributes);
117 return m_pAttributes->GetUINT32(guidKey, punValue);
118 }
119
120 STDMETHODIMP GetUINT64(REFGUID guidKey, UINT64* punValue)
121 {
122 assert(m_pAttributes);
123 return m_pAttributes->GetUINT64(guidKey, punValue);
124 }
125
126 STDMETHODIMP GetDouble(REFGUID guidKey, double* pfValue)
127 {
128 assert(m_pAttributes);
129 return m_pAttributes->GetDouble(guidKey, pfValue);
130 }
131
132 STDMETHODIMP GetGUID(REFGUID guidKey, GUID* pguidValue)
133 {
134 assert(m_pAttributes);
135 return m_pAttributes->GetGUID(guidKey, pguidValue);
136 }
137
138 STDMETHODIMP GetStringLength(REFGUID guidKey, UINT32* pcchLength)
139 {
140 assert(m_pAttributes);
141 return m_pAttributes->GetStringLength(guidKey, pcchLength);
142 }
143
144 STDMETHODIMP GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength)
145 {
146 assert(m_pAttributes);
147 return m_pAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
148 }
149
150 STDMETHODIMP GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength)
151 {
152 assert(m_pAttributes);
153 return m_pAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
154 }
155
156 STDMETHODIMP GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize)
157 {
158 assert(m_pAttributes);
159 return m_pAttributes->GetBlobSize(guidKey, pcbBlobSize);
160 }
161
162 STDMETHODIMP GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize)
163 {
164 assert(m_pAttributes);
165 return m_pAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
166 }
167
168 STDMETHODIMP GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize)
169 {
170 assert(m_pAttributes);
171 return m_pAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
172 }
173
174 STDMETHODIMP GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv)
175 {
176 assert(m_pAttributes);
177 return m_pAttributes->GetUnknown(guidKey, riid, ppv);
178 }
179
180 STDMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value)
181 {
182 assert(m_pAttributes);
183 return m_pAttributes->SetItem(guidKey, Value);
184 }
185
186 STDMETHODIMP DeleteItem(REFGUID guidKey)
187 {
188 assert(m_pAttributes);
189 return m_pAttributes->DeleteItem(guidKey);
190 }
191
192 STDMETHODIMP DeleteAllItems()
193 {
194 assert(m_pAttributes);
195 return m_pAttributes->DeleteAllItems();
196 }
197
198 STDMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue)
199 {
200 assert(m_pAttributes);
201 return m_pAttributes->SetUINT32(guidKey, unValue);
202 }
203
204 STDMETHODIMP SetUINT64(REFGUID guidKey,UINT64 unValue)
205 {
206 assert(m_pAttributes);
207 return m_pAttributes->SetUINT64(guidKey, unValue);
208 }
209
210 STDMETHODIMP SetDouble(REFGUID guidKey, double fValue)
211 {
212 assert(m_pAttributes);
213 return m_pAttributes->SetDouble(guidKey, fValue);
214 }
215
216 STDMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue)
217 {
218 assert(m_pAttributes);
219 return m_pAttributes->SetGUID(guidKey, guidValue);
220 }
221
222 STDMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue)
223 {
224 assert(m_pAttributes);
225 return m_pAttributes->SetString(guidKey, wszValue);
226 }
227
228 STDMETHODIMP SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize)
229 {
230 assert(m_pAttributes);
231 return m_pAttributes->SetBlob(guidKey, pBuf, cbBufSize);
232 }
233
234 STDMETHODIMP SetUnknown(REFGUID guidKey, IUnknown* pUnknown)
235 {
236 assert(m_pAttributes);
237 return m_pAttributes->SetUnknown(guidKey, pUnknown);
238 }
239
240 STDMETHODIMP LockStore()
241 {
242 assert(m_pAttributes);
243 return m_pAttributes->LockStore();
244 }
245
246 STDMETHODIMP UnlockStore()
247 {
248 assert(m_pAttributes);
249 return m_pAttributes->UnlockStore();
250 }
251
252 STDMETHODIMP GetCount(UINT32* pcItems)
253 {
254 assert(m_pAttributes);
255 return m_pAttributes->GetCount(pcItems);
256 }
257
258 STDMETHODIMP GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue)
259 {
260 assert(m_pAttributes);
261 return m_pAttributes->GetItemByIndex(unIndex, pguidKey, pValue);
262 }
263
264 STDMETHODIMP CopyAllItems(IMFAttributes* pDest)
265 {
266 assert(m_pAttributes);
267 return m_pAttributes->CopyAllItems(pDest);
268 }
269
270 // Helper functions
271
272 HRESULT SerializeToStream(DWORD dwOptions, IStream* pStm)
273 // dwOptions: Flags from MF_ATTRIBUTE_SERIALIZE_OPTIONS
274 {
275 assert(m_pAttributes);
276 return MFSerializeAttributesToStream(m_pAttributes, dwOptions, pStm);
277 }
278
279 HRESULT DeserializeFromStream(DWORD dwOptions, IStream* pStm)
280 {
281 assert(m_pAttributes);
282 return MFDeserializeAttributesFromStream(m_pAttributes, dwOptions, pStm);
283 }
284
285 // SerializeToBlob: Stores the attributes in a byte array.
286 //
287 // ppBuf: Receives a pointer to the byte array.
288 // pcbSize: Receives the size of the byte array.
289 //
290 // The caller must free the array using CoTaskMemFree.
291 HRESULT SerializeToBlob(UINT8 **ppBuffer, UINT32 *pcbSize)
292 {
293 assert(m_pAttributes);
294
295 if (ppBuffer == NULL)
296 {
297 return E_POINTER;
298 }
299 if (pcbSize == NULL)
300 {
301 return E_POINTER;
302 }
303
304 *ppBuffer = NULL;
305 *pcbSize = 0;
306
307 UINT32 cbSize = 0;
308 BYTE *pBuffer = NULL;
309
310 HRESULT hr = MFGetAttributesAsBlobSize(m_pAttributes, &cbSize);
311
312 if (FAILED(hr))
313 {
314 return hr;
315 }
316
317 pBuffer = (BYTE*)CoTaskMemAlloc(cbSize);
318 if (pBuffer == NULL)
319 {
320 return E_OUTOFMEMORY;
321 }
322
323 hr = MFGetAttributesAsBlob(m_pAttributes, pBuffer, cbSize);
324
325 if (SUCCEEDED(hr))
326 {
327 *ppBuffer = pBuffer;
328 *pcbSize = cbSize;
329 }
330 else
331 {
332 CoTaskMemFree(pBuffer);
333 }
334 return hr;
335 }
336
337 HRESULT DeserializeFromBlob(const UINT8* pBuffer, UINT cbSize)
338 {
339 assert(m_pAttributes);
340 return MFInitAttributesFromBlob(m_pAttributes, pBuffer, cbSize);
341 }
342
343 HRESULT GetRatio(REFGUID guidKey, UINT32* pnNumerator, UINT32* punDenominator)
344 {
345 assert(m_pAttributes);
346 return MFGetAttributeRatio(m_pAttributes, guidKey, pnNumerator, punDenominator);
347 }
348
349 HRESULT SetRatio(REFGUID guidKey, UINT32 unNumerator, UINT32 unDenominator)
350 {
351 assert(m_pAttributes);
352 return MFSetAttributeRatio(m_pAttributes, guidKey, unNumerator, unDenominator);
353 }
354
355 // Gets an attribute whose value represents the size of something (eg a video frame).
356 HRESULT GetSize(REFGUID guidKey, UINT32* punWidth, UINT32* punHeight)
357 {
358 assert(m_pAttributes);
359 return MFGetAttributeSize(m_pAttributes, guidKey, punWidth, punHeight);
360 }
361
362 // Sets an attribute whose value represents the size of something (eg a video frame).
363 HRESULT SetSize(REFGUID guidKey, UINT32 unWidth, UINT32 unHeight)
364 {
365 assert(m_pAttributes);
366 return MFSetAttributeSize (m_pAttributes, guidKey, unWidth, unHeight);
367 }
368 };