官方英文文档链接:https://docs.microsoft.com/en-us/windows/desktop/medfound/media-foundation-primitives
基于05/31/2018
?
Media Foundation 定义了几种在整个 Media Foundation API 中都会用到的基本对象类型。
Topic |
Description |
Attributes |
Attributes 和 properties 是存储在对象中的键值对 |
Media Types |
描述媒体格式 |
Media Buffers |
管理一块内存,并且可以在对象之间分享 |
Media Samples |
是包含了 media buffer 列表的对象 |
官方英文文档链接:https://docs.microsoft.com/en-us/windows/desktop/medfound/attributes-and-properties
基于05/31/2018
?
Attribute(属性) 是键值对,key 是 GUID,value 是一个 PROPVARIANT。Microsoft Media Foundation 中使用 attribute 用来配置对象,描述媒体格式,查询对象属性等等。
此文包含以下内容。
- About Attributes
- Serializing Attributes
- Implementing IMFAttributes
- Related topics
About Attributes
Attribute 是键值对,key 是 GUID,value 是一个 PROPVARIANT。Attribute 值仅限以下几种类型:
- Unsigned 32-bit integer (UINT32).
- Unsigned 64-bit integer (UINT64).
- 64-bit floating-point number.
- GUID.
- Null-terminated wide-character string.
- Byte array.
-
IUnknown pointer.
这些类型定义在 MF_ATTRIBUTE_TYPE 枚举中。如果需要设置或检索?Attribute,使用 IMFAttributes 接口。这个接口在设置数据的时候会使用“类型安全”(就是根据数据类型调用不同的方法)的方法。例如要设置一个32位 int,就调用 IMFAttributes::SetUINT32。 Attribute keys 在一个对象中是唯一的,如果对同一个 key 设置了两次不同的数值,那么第二次会覆盖第一次。
很多 Media Foundation 接口都继承了 IMFAttributes 接口。应用程序应该通过对象设置这些属性,bjects that expose this interface have optional or mandatory attributes that the application should set on the object,or have attributes that the application can retrieve. 此外,某些方法将 IMFAttributes 指针作为参数传递,使应用程序能够进行设置。应用程序必须创建一个新的 attribute 对象来存储设置。要创建新的 attribute ,调用 MFCreateAttributes。
下面的代码包含两个方法。第一个方法创建了一个新的 attribute 对象来存储设置,这个属性叫做 MY_ATTRIBUTE ,值是一个 string。第二个函数获取此属性的值。
?
有关 Media Foundation 属性(attribute)的完整列表,查看 Media Foundation Attributes。. The expected data type for each attribute is documented there.
Serializing Attributes(序列化属性)
Media Foundation 有两个用于属性序列化存储的方法。一个是将属性写入一个数组,另一个是将属性写入支持 IStream 接口的流。每个方法都有一个对应的函数来加载属性(就是反向,还原)
Operation |
Byte Array |
IStream |
存储 |
MFGetAttributesAsBlob |
MFSerializeAttributesToStream |
加载 |
MFInitAttributesFromBlob |
MFDeserializeAttributesFromStream |
?
要将属性存储的内容写入数组,调用 MFGetAttributesAsBlob。值为 IUnknow 指针的属性将被忽略(?原话Attributes with IUnknown pointer values are ignored.)。要将属性加载回 attribute,调用 MFInitAttributesFromBlob。
若要将属性存储写入流,调用 MFSerializeAttributesToStream。这个方法可以封装发送 IUnknown 指针值。调用者必须提供实现了 IStream 接口的对象。要把属性从流加载回 attribute 对象,调用 MFDeserializeAttributesFromStream。
Implementing IMFAttributes
Media Foundation 提供了 IMFAttributes 的(stock implementation),包含在 MFCreateAttributes 中。大多数情况下应使用此实现。
不过这里有一种情况你需要自己去实现 IMFAttributes 接口:如果你要实现一个继承自 IMFAttributes 的接口,在这种情况下,你必须自己实现 IMFAttributes 的各个方法。
在这种情况下,建议建议包装 Media Foundation 对 IMFAttributes 的现有实现。下面的代码展示了一个类模板,该类包含一个 IMFAttributes 指针和所有的 IMFAttributes 方法(IUnknown除外)。
?
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,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,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,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,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,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,unWidth,unHeight);
367 }
368 };
?

下面的代码展示了如何用这个类模板来实例化一个类:
?
你必须调用 CBaseAttributes::Initialize 来创建一个 attribute store。在上面的代码中,这一步在一个静态的创建方法(static HRESULT CreateInstance(MyObject **ppObject);)中完成。?
模板参数是一个接口类型,默认是 IMFAttributes 。如果要实例化继承自 IMFAttributes 的接口,例如 IMFActivate,设置模板参数为派生接口名称即可。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|