setupapi: Add stub for CM_Get_Device_Interface_Alias{A,W}.
[wine.git] / dlls / mfplat / mediatype.c
blobf92577a9cbcb32c0400ae4be52ce470ded27da1c
1 /*
2 * Copyright 2017 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include "mfplat_private.h"
23 #include "initguid.h"
24 #include "ks.h"
25 #include "ksmedia.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
31 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
32 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
33 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
34 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
36 struct media_type
38 struct attributes attributes;
39 IMFMediaType IMFMediaType_iface;
42 struct stream_desc
44 struct attributes attributes;
45 IMFStreamDescriptor IMFStreamDescriptor_iface;
46 IMFMediaTypeHandler IMFMediaTypeHandler_iface;
47 DWORD identifier;
48 IMFMediaType **media_types;
49 unsigned int media_types_count;
50 IMFMediaType *current_type;
53 struct presentation_desc_entry
55 IMFStreamDescriptor *descriptor;
56 BOOL selected;
59 struct presentation_desc
61 struct attributes attributes;
62 IMFPresentationDescriptor IMFPresentationDescriptor_iface;
63 struct presentation_desc_entry *descriptors;
64 unsigned int count;
67 static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count);
69 static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface)
71 return CONTAINING_RECORD(iface, struct media_type, IMFMediaType_iface);
74 static inline struct stream_desc *impl_from_IMFStreamDescriptor(IMFStreamDescriptor *iface)
76 return CONTAINING_RECORD(iface, struct stream_desc, IMFStreamDescriptor_iface);
79 static struct stream_desc *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface)
81 return CONTAINING_RECORD(iface, struct stream_desc, IMFMediaTypeHandler_iface);
84 static struct presentation_desc *impl_from_IMFPresentationDescriptor(IMFPresentationDescriptor *iface)
86 return CONTAINING_RECORD(iface, struct presentation_desc, IMFPresentationDescriptor_iface);
89 static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out)
91 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
93 if (IsEqualIID(riid, &IID_IMFMediaType) ||
94 IsEqualIID(riid, &IID_IMFAttributes) ||
95 IsEqualIID(riid, &IID_IUnknown))
97 *out = iface;
98 IMFMediaType_AddRef(iface);
99 return S_OK;
102 WARN("Unsupported %s.\n", debugstr_guid(riid));
103 *out = NULL;
104 return E_NOINTERFACE;
107 static ULONG WINAPI mediatype_AddRef(IMFMediaType *iface)
109 struct media_type *media_type = impl_from_IMFMediaType(iface);
110 ULONG refcount = InterlockedIncrement(&media_type->attributes.ref);
112 TRACE("%p, refcount %u.\n", iface, refcount);
114 return refcount;
117 static ULONG WINAPI mediatype_Release(IMFMediaType *iface)
119 struct media_type *media_type = impl_from_IMFMediaType(iface);
120 ULONG refcount = InterlockedDecrement(&media_type->attributes.ref);
122 TRACE("%p, refcount %u.\n", iface, refcount);
124 if (!refcount)
126 clear_attributes_object(&media_type->attributes);
127 heap_free(media_type);
130 return refcount;
133 static HRESULT WINAPI mediatype_GetItem(IMFMediaType *iface, REFGUID key, PROPVARIANT *value)
135 struct media_type *media_type = impl_from_IMFMediaType(iface);
137 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
139 return attributes_GetItem(&media_type->attributes, key, value);
142 static HRESULT WINAPI mediatype_GetItemType(IMFMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
144 struct media_type *media_type = impl_from_IMFMediaType(iface);
146 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
148 return attributes_GetItemType(&media_type->attributes, key, type);
151 static HRESULT WINAPI mediatype_CompareItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
153 struct media_type *media_type = impl_from_IMFMediaType(iface);
155 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
157 return attributes_CompareItem(&media_type->attributes, key, value, result);
160 static HRESULT WINAPI mediatype_Compare(IMFMediaType *iface, IMFAttributes *attrs, MF_ATTRIBUTES_MATCH_TYPE type,
161 BOOL *result)
163 struct media_type *media_type = impl_from_IMFMediaType(iface);
165 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
167 return attributes_Compare(&media_type->attributes, attrs, type, result);
170 static HRESULT WINAPI mediatype_GetUINT32(IMFMediaType *iface, REFGUID key, UINT32 *value)
172 struct media_type *media_type = impl_from_IMFMediaType(iface);
174 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
176 return attributes_GetUINT32(&media_type->attributes, key, value);
179 static HRESULT WINAPI mediatype_GetUINT64(IMFMediaType *iface, REFGUID key, UINT64 *value)
181 struct media_type *media_type = impl_from_IMFMediaType(iface);
183 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
185 return attributes_GetUINT64(&media_type->attributes, key, value);
188 static HRESULT WINAPI mediatype_GetDouble(IMFMediaType *iface, REFGUID key, double *value)
190 struct media_type *media_type = impl_from_IMFMediaType(iface);
192 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
194 return attributes_GetDouble(&media_type->attributes, key, value);
197 static HRESULT WINAPI mediatype_GetGUID(IMFMediaType *iface, REFGUID key, GUID *value)
199 struct media_type *media_type = impl_from_IMFMediaType(iface);
201 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
203 return attributes_GetGUID(&media_type->attributes, key, value);
206 static HRESULT WINAPI mediatype_GetStringLength(IMFMediaType *iface, REFGUID key, UINT32 *length)
208 struct media_type *media_type = impl_from_IMFMediaType(iface);
210 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
212 return attributes_GetStringLength(&media_type->attributes, key, length);
215 static HRESULT WINAPI mediatype_GetString(IMFMediaType *iface, REFGUID key, WCHAR *value,
216 UINT32 size, UINT32 *length)
218 struct media_type *media_type = impl_from_IMFMediaType(iface);
220 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
222 return attributes_GetString(&media_type->attributes, key, value, size, length);
225 static HRESULT WINAPI mediatype_GetAllocatedString(IMFMediaType *iface, REFGUID key,
226 WCHAR **value, UINT32 *length)
228 struct media_type *media_type = impl_from_IMFMediaType(iface);
230 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
232 return attributes_GetAllocatedString(&media_type->attributes, key, value, length);
235 static HRESULT WINAPI mediatype_GetBlobSize(IMFMediaType *iface, REFGUID key, UINT32 *size)
237 struct media_type *media_type = impl_from_IMFMediaType(iface);
239 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
241 return attributes_GetBlobSize(&media_type->attributes, key, size);
244 static HRESULT WINAPI mediatype_GetBlob(IMFMediaType *iface, REFGUID key, UINT8 *buf,
245 UINT32 bufsize, UINT32 *blobsize)
247 struct media_type *media_type = impl_from_IMFMediaType(iface);
249 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
251 return attributes_GetBlob(&media_type->attributes, key, buf, bufsize, blobsize);
254 static HRESULT WINAPI mediatype_GetAllocatedBlob(IMFMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size)
256 struct media_type *media_type = impl_from_IMFMediaType(iface);
258 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
260 return attributes_GetAllocatedBlob(&media_type->attributes, key, buf, size);
263 static HRESULT WINAPI mediatype_GetUnknown(IMFMediaType *iface, REFGUID key, REFIID riid, void **obj)
265 struct media_type *media_type = impl_from_IMFMediaType(iface);
267 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), obj);
269 return attributes_GetUnknown(&media_type->attributes, key, riid, obj);
272 static HRESULT WINAPI mediatype_SetItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value)
274 struct media_type *media_type = impl_from_IMFMediaType(iface);
276 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
278 return attributes_SetItem(&media_type->attributes, key, value);
281 static HRESULT WINAPI mediatype_DeleteItem(IMFMediaType *iface, REFGUID key)
283 struct media_type *media_type = impl_from_IMFMediaType(iface);
285 TRACE("%p, %s.\n", iface, debugstr_attr(key));
287 return attributes_DeleteItem(&media_type->attributes, key);
290 static HRESULT WINAPI mediatype_DeleteAllItems(IMFMediaType *iface)
292 struct media_type *media_type = impl_from_IMFMediaType(iface);
294 TRACE("%p.\n", iface);
296 return attributes_DeleteAllItems(&media_type->attributes);
299 static HRESULT WINAPI mediatype_SetUINT32(IMFMediaType *iface, REFGUID key, UINT32 value)
301 struct media_type *media_type = impl_from_IMFMediaType(iface);
303 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
305 return attributes_SetUINT32(&media_type->attributes, key, value);
308 static HRESULT WINAPI mediatype_SetUINT64(IMFMediaType *iface, REFGUID key, UINT64 value)
310 struct media_type *media_type = impl_from_IMFMediaType(iface);
312 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
314 return attributes_SetUINT64(&media_type->attributes, key, value);
317 static HRESULT WINAPI mediatype_SetDouble(IMFMediaType *iface, REFGUID key, double value)
319 struct media_type *media_type = impl_from_IMFMediaType(iface);
321 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
323 return attributes_SetDouble(&media_type->attributes, key, value);
326 static HRESULT WINAPI mediatype_SetGUID(IMFMediaType *iface, REFGUID key, REFGUID value)
328 struct media_type *media_type = impl_from_IMFMediaType(iface);
330 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
332 return attributes_SetGUID(&media_type->attributes, key, value);
335 static HRESULT WINAPI mediatype_SetString(IMFMediaType *iface, REFGUID key, const WCHAR *value)
337 struct media_type *media_type = impl_from_IMFMediaType(iface);
339 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
341 return attributes_SetString(&media_type->attributes, key, value);
344 static HRESULT WINAPI mediatype_SetBlob(IMFMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size)
346 struct media_type *media_type = impl_from_IMFMediaType(iface);
348 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
350 return attributes_SetBlob(&media_type->attributes, key, buf, size);
353 static HRESULT WINAPI mediatype_SetUnknown(IMFMediaType *iface, REFGUID key, IUnknown *unknown)
355 struct media_type *media_type = impl_from_IMFMediaType(iface);
357 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
359 return attributes_SetUnknown(&media_type->attributes, key, unknown);
362 static HRESULT WINAPI mediatype_LockStore(IMFMediaType *iface)
364 struct media_type *media_type = impl_from_IMFMediaType(iface);
366 TRACE("%p.\n", iface);
368 return attributes_LockStore(&media_type->attributes);
371 static HRESULT WINAPI mediatype_UnlockStore(IMFMediaType *iface)
373 struct media_type *media_type = impl_from_IMFMediaType(iface);
375 TRACE("%p.\n", iface);
377 return attributes_UnlockStore(&media_type->attributes);
380 static HRESULT WINAPI mediatype_GetCount(IMFMediaType *iface, UINT32 *count)
382 struct media_type *media_type = impl_from_IMFMediaType(iface);
384 TRACE("%p, %p.\n", iface, count);
386 return attributes_GetCount(&media_type->attributes, count);
389 static HRESULT WINAPI mediatype_GetItemByIndex(IMFMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value)
391 struct media_type *media_type = impl_from_IMFMediaType(iface);
393 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
395 return attributes_GetItemByIndex(&media_type->attributes, index, key, value);
398 static HRESULT WINAPI mediatype_CopyAllItems(IMFMediaType *iface, IMFAttributes *dest)
400 struct media_type *media_type = impl_from_IMFMediaType(iface);
402 TRACE("%p, %p.\n", iface, dest);
404 return attributes_CopyAllItems(&media_type->attributes, dest);
407 static HRESULT WINAPI mediatype_GetMajorType(IMFMediaType *iface, GUID *guid)
409 struct media_type *media_type = impl_from_IMFMediaType(iface);
411 TRACE("%p, %p.\n", iface, guid);
413 return attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, guid);
416 static HRESULT WINAPI mediatype_IsCompressedFormat(IMFMediaType *iface, BOOL *compressed)
418 struct media_type *media_type = impl_from_IMFMediaType(iface);
419 UINT32 value;
421 TRACE("%p, %p.\n", iface, compressed);
423 if (FAILED(attributes_GetUINT32(&media_type->attributes, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value)))
425 value = 0;
428 *compressed = !value;
430 return S_OK;
433 static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type, DWORD *flags)
435 const DWORD full_equality_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES |
436 MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA;
437 struct media_type *media_type = impl_from_IMFMediaType(iface);
438 struct comparand
440 IMFAttributes *type;
441 PROPVARIANT value;
442 UINT32 count;
443 GUID guid;
444 HRESULT hr;
445 } left, right, swp;
446 unsigned int i;
447 BOOL result;
449 TRACE("%p, %p, %p.\n", iface, type, flags);
451 *flags = 0;
453 left.type = &media_type->attributes.IMFAttributes_iface;
454 right.type = (IMFAttributes *)type;
456 if (FAILED(IMFAttributes_GetGUID(left.type, &MF_MT_MAJOR_TYPE, &left.guid)))
457 return E_INVALIDARG;
459 if (FAILED(IMFAttributes_GetGUID(right.type, &MF_MT_MAJOR_TYPE, &right.guid)))
460 return E_INVALIDARG;
462 if (IsEqualGUID(&left.guid, &right.guid))
463 *flags |= MF_MEDIATYPE_EQUAL_MAJOR_TYPES;
465 /* Subtypes equal or both missing. */
466 left.hr = IMFAttributes_GetGUID(left.type, &MF_MT_SUBTYPE, &left.guid);
467 right.hr = IMFAttributes_GetGUID(right.type, &MF_MT_SUBTYPE, &right.guid);
469 if ((SUCCEEDED(left.hr) && SUCCEEDED(right.hr) && IsEqualGUID(&left.guid, &right.guid)) ||
470 (FAILED(left.hr) && FAILED(right.hr)))
472 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_TYPES;
475 /* Format data */
476 IMFAttributes_GetCount(left.type, &left.count);
477 IMFAttributes_GetCount(right.type, &right.count);
479 if (right.count < left.count)
481 swp = left;
482 left = right;
483 right = swp;
486 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_DATA;
488 for (i = 0; i < left.count; ++i)
490 PROPVARIANT value;
491 GUID key;
493 if (SUCCEEDED(IMFAttributes_GetItemByIndex(left.type, i, &key, &value)))
495 if (IsEqualGUID(&key, &MF_MT_USER_DATA) ||
496 IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MIN) ||
497 IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MAX))
499 PropVariantClear(&value);
500 continue;
503 result = FALSE;
504 IMFAttributes_CompareItem(right.type, &key, &value, &result);
505 PropVariantClear(&value);
506 if (!result)
508 *flags &= ~MF_MEDIATYPE_EQUAL_FORMAT_DATA;
509 break;
514 /* User data */
515 PropVariantInit(&left.value);
516 left.hr = IMFAttributes_GetItem(left.type, &MF_MT_USER_DATA, &left.value);
517 PropVariantInit(&right.value);
518 right.hr = IMFAttributes_GetItem(right.type, &MF_MT_USER_DATA, &right.value);
520 /* Compare user data if both types have it, otherwise simply check if both don't. */
521 if (SUCCEEDED(left.hr) && SUCCEEDED(right.hr))
523 result = FALSE;
524 IMFAttributes_CompareItem(left.type, &MF_MT_USER_DATA, &left.value, &result);
526 else
527 result = FAILED(left.hr) && FAILED(right.hr);
529 PropVariantClear(&left.value);
530 PropVariantClear(&right.value);
532 if (result)
533 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA;
535 return *flags == full_equality_flags ? S_OK : S_FALSE;
538 static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation)
540 FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
542 return E_NOTIMPL;
545 static HRESULT WINAPI mediatype_FreeRepresentation(IMFMediaType *iface, GUID guid, void *representation)
547 FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
549 return E_NOTIMPL;
552 static const IMFMediaTypeVtbl mediatypevtbl =
554 mediatype_QueryInterface,
555 mediatype_AddRef,
556 mediatype_Release,
557 mediatype_GetItem,
558 mediatype_GetItemType,
559 mediatype_CompareItem,
560 mediatype_Compare,
561 mediatype_GetUINT32,
562 mediatype_GetUINT64,
563 mediatype_GetDouble,
564 mediatype_GetGUID,
565 mediatype_GetStringLength,
566 mediatype_GetString,
567 mediatype_GetAllocatedString,
568 mediatype_GetBlobSize,
569 mediatype_GetBlob,
570 mediatype_GetAllocatedBlob,
571 mediatype_GetUnknown,
572 mediatype_SetItem,
573 mediatype_DeleteItem,
574 mediatype_DeleteAllItems,
575 mediatype_SetUINT32,
576 mediatype_SetUINT64,
577 mediatype_SetDouble,
578 mediatype_SetGUID,
579 mediatype_SetString,
580 mediatype_SetBlob,
581 mediatype_SetUnknown,
582 mediatype_LockStore,
583 mediatype_UnlockStore,
584 mediatype_GetCount,
585 mediatype_GetItemByIndex,
586 mediatype_CopyAllItems,
587 mediatype_GetMajorType,
588 mediatype_IsCompressedFormat,
589 mediatype_IsEqual,
590 mediatype_GetRepresentation,
591 mediatype_FreeRepresentation
594 /***********************************************************************
595 * MFCreateMediaType (mfplat.@)
597 HRESULT WINAPI MFCreateMediaType(IMFMediaType **media_type)
599 struct media_type *object;
600 HRESULT hr;
602 TRACE("%p.\n", media_type);
604 if (!media_type)
605 return E_INVALIDARG;
607 object = heap_alloc(sizeof(*object));
608 if (!object)
609 return E_OUTOFMEMORY;
611 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
613 heap_free(object);
614 return hr;
616 object->IMFMediaType_iface.lpVtbl = &mediatypevtbl;
618 *media_type = &object->IMFMediaType_iface;
620 TRACE("Created media type %p.\n", *media_type);
622 return S_OK;
625 static HRESULT WINAPI stream_descriptor_QueryInterface(IMFStreamDescriptor *iface, REFIID riid, void **out)
627 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
629 if (IsEqualIID(riid, &IID_IMFStreamDescriptor) ||
630 IsEqualIID(riid, &IID_IMFAttributes) ||
631 IsEqualIID(riid, &IID_IUnknown))
633 *out = iface;
634 IMFStreamDescriptor_AddRef(iface);
635 return S_OK;
638 WARN("Unsupported %s.\n", debugstr_guid(riid));
639 *out = NULL;
640 return E_NOINTERFACE;
643 static ULONG WINAPI stream_descriptor_AddRef(IMFStreamDescriptor *iface)
645 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
646 ULONG refcount = InterlockedIncrement(&stream_desc->attributes.ref);
648 TRACE("%p, refcount %u.\n", iface, refcount);
650 return refcount;
653 static ULONG WINAPI stream_descriptor_Release(IMFStreamDescriptor *iface)
655 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
656 ULONG refcount = InterlockedDecrement(&stream_desc->attributes.ref);
657 unsigned int i;
659 TRACE("%p, refcount %u.\n", iface, refcount);
661 if (!refcount)
663 for (i = 0; i < stream_desc->media_types_count; ++i)
665 if (stream_desc->media_types[i])
666 IMFMediaType_Release(stream_desc->media_types[i]);
668 heap_free(stream_desc->media_types);
669 if (stream_desc->current_type)
670 IMFMediaType_Release(stream_desc->current_type);
671 clear_attributes_object(&stream_desc->attributes);
672 heap_free(stream_desc);
675 return refcount;
678 static HRESULT WINAPI stream_descriptor_GetItem(IMFStreamDescriptor *iface, REFGUID key, PROPVARIANT *value)
680 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
682 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
684 return attributes_GetItem(&stream_desc->attributes, key, value);
687 static HRESULT WINAPI stream_descriptor_GetItemType(IMFStreamDescriptor *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
689 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
691 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
693 return attributes_GetItemType(&stream_desc->attributes, key, type);
696 static HRESULT WINAPI stream_descriptor_CompareItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value,
697 BOOL *result)
699 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
701 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
703 return attributes_CompareItem(&stream_desc->attributes, key, value, result);
706 static HRESULT WINAPI stream_descriptor_Compare(IMFStreamDescriptor *iface, IMFAttributes *theirs,
707 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
709 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
711 TRACE("%p, %p, %d, %p.\n", iface, theirs, type, result);
713 return attributes_Compare(&stream_desc->attributes, theirs, type, result);
716 static HRESULT WINAPI stream_descriptor_GetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 *value)
718 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
720 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
722 return attributes_GetUINT32(&stream_desc->attributes, key, value);
725 static HRESULT WINAPI stream_descriptor_GetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 *value)
727 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
729 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
731 return attributes_GetUINT64(&stream_desc->attributes, key, value);
734 static HRESULT WINAPI stream_descriptor_GetDouble(IMFStreamDescriptor *iface, REFGUID key, double *value)
736 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
738 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
740 return attributes_GetDouble(&stream_desc->attributes, key, value);
743 static HRESULT WINAPI stream_descriptor_GetGUID(IMFStreamDescriptor *iface, REFGUID key, GUID *value)
745 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
747 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
749 return attributes_GetGUID(&stream_desc->attributes, key, value);
752 static HRESULT WINAPI stream_descriptor_GetStringLength(IMFStreamDescriptor *iface, REFGUID key, UINT32 *length)
754 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
756 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
758 return attributes_GetStringLength(&stream_desc->attributes, key, length);
761 static HRESULT WINAPI stream_descriptor_GetString(IMFStreamDescriptor *iface, REFGUID key, WCHAR *value,
762 UINT32 size, UINT32 *length)
764 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
766 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
768 return attributes_GetString(&stream_desc->attributes, key, value, size, length);
771 static HRESULT WINAPI stream_descriptor_GetAllocatedString(IMFStreamDescriptor *iface, REFGUID key,
772 WCHAR **value, UINT32 *length)
774 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
776 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
778 return attributes_GetAllocatedString(&stream_desc->attributes, key, value, length);
781 static HRESULT WINAPI stream_descriptor_GetBlobSize(IMFStreamDescriptor *iface, REFGUID key, UINT32 *size)
783 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
785 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
787 return attributes_GetBlobSize(&stream_desc->attributes, key, size);
790 static HRESULT WINAPI stream_descriptor_GetBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 *buf,
791 UINT32 bufsize, UINT32 *blobsize)
793 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
795 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
797 return attributes_GetBlob(&stream_desc->attributes, key, buf, bufsize, blobsize);
800 static HRESULT WINAPI stream_descriptor_GetAllocatedBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 **buf,
801 UINT32 *size)
803 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
805 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
807 return attributes_GetAllocatedBlob(&stream_desc->attributes, key, buf, size);
810 static HRESULT WINAPI stream_descriptor_GetUnknown(IMFStreamDescriptor *iface, REFGUID key, REFIID riid, void **out)
812 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
814 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), out);
816 return attributes_GetUnknown(&stream_desc->attributes, key, riid, out);
819 static HRESULT WINAPI stream_descriptor_SetItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value)
821 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
823 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
825 return attributes_SetItem(&stream_desc->attributes, key, value);
828 static HRESULT WINAPI stream_descriptor_DeleteItem(IMFStreamDescriptor *iface, REFGUID key)
830 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
832 TRACE("%p, %s.\n", iface, debugstr_attr(key));
834 return attributes_DeleteItem(&stream_desc->attributes, key);
837 static HRESULT WINAPI stream_descriptor_DeleteAllItems(IMFStreamDescriptor *iface)
839 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
841 TRACE("%p.\n", iface);
843 return attributes_DeleteAllItems(&stream_desc->attributes);
846 static HRESULT WINAPI stream_descriptor_SetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 value)
848 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
850 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
852 return attributes_SetUINT32(&stream_desc->attributes, key, value);
855 static HRESULT WINAPI stream_descriptor_SetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 value)
857 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
859 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
861 return attributes_SetUINT64(&stream_desc->attributes, key, value);
864 static HRESULT WINAPI stream_descriptor_SetDouble(IMFStreamDescriptor *iface, REFGUID key, double value)
866 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
868 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
870 return attributes_SetDouble(&stream_desc->attributes, key, value);
873 static HRESULT WINAPI stream_descriptor_SetGUID(IMFStreamDescriptor *iface, REFGUID key, REFGUID value)
875 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
877 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
879 return attributes_SetGUID(&stream_desc->attributes, key, value);
882 static HRESULT WINAPI stream_descriptor_SetString(IMFStreamDescriptor *iface, REFGUID key, const WCHAR *value)
884 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
886 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
888 return attributes_SetString(&stream_desc->attributes, key, value);
891 static HRESULT WINAPI stream_descriptor_SetBlob(IMFStreamDescriptor *iface, REFGUID key, const UINT8 *buf, UINT32 size)
893 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
895 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
897 return attributes_SetBlob(&stream_desc->attributes, key, buf, size);
900 static HRESULT WINAPI stream_descriptor_SetUnknown(IMFStreamDescriptor *iface, REFGUID key, IUnknown *unknown)
902 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
904 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
906 return attributes_SetUnknown(&stream_desc->attributes, key, unknown);
909 static HRESULT WINAPI stream_descriptor_LockStore(IMFStreamDescriptor *iface)
911 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
913 TRACE("%p.\n", iface);
915 return attributes_LockStore(&stream_desc->attributes);
918 static HRESULT WINAPI stream_descriptor_UnlockStore(IMFStreamDescriptor *iface)
920 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
922 TRACE("%p.\n", iface);
924 return attributes_UnlockStore(&stream_desc->attributes);
927 static HRESULT WINAPI stream_descriptor_GetCount(IMFStreamDescriptor *iface, UINT32 *count)
929 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
931 TRACE("%p, %p.\n", iface, count);
933 return attributes_GetCount(&stream_desc->attributes, count);
936 static HRESULT WINAPI stream_descriptor_GetItemByIndex(IMFStreamDescriptor *iface, UINT32 index, GUID *key,
937 PROPVARIANT *value)
939 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
941 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
943 return attributes_GetItemByIndex(&stream_desc->attributes, index, key, value);
946 static HRESULT WINAPI stream_descriptor_CopyAllItems(IMFStreamDescriptor *iface, IMFAttributes *dest)
948 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
950 TRACE("%p, %p.\n", iface, dest);
952 return attributes_CopyAllItems(&stream_desc->attributes, dest);
955 static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier)
957 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
959 TRACE("%p, %p.\n", iface, identifier);
961 *identifier = stream_desc->identifier;
963 return S_OK;
966 static HRESULT WINAPI stream_descriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler)
968 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
970 TRACE("%p, %p.\n", iface, handler);
972 *handler = &stream_desc->IMFMediaTypeHandler_iface;
973 IMFMediaTypeHandler_AddRef(*handler);
975 return S_OK;
978 static const IMFStreamDescriptorVtbl streamdescriptorvtbl =
980 stream_descriptor_QueryInterface,
981 stream_descriptor_AddRef,
982 stream_descriptor_Release,
983 stream_descriptor_GetItem,
984 stream_descriptor_GetItemType,
985 stream_descriptor_CompareItem,
986 stream_descriptor_Compare,
987 stream_descriptor_GetUINT32,
988 stream_descriptor_GetUINT64,
989 stream_descriptor_GetDouble,
990 stream_descriptor_GetGUID,
991 stream_descriptor_GetStringLength,
992 stream_descriptor_GetString,
993 stream_descriptor_GetAllocatedString,
994 stream_descriptor_GetBlobSize,
995 stream_descriptor_GetBlob,
996 stream_descriptor_GetAllocatedBlob,
997 stream_descriptor_GetUnknown,
998 stream_descriptor_SetItem,
999 stream_descriptor_DeleteItem,
1000 stream_descriptor_DeleteAllItems,
1001 stream_descriptor_SetUINT32,
1002 stream_descriptor_SetUINT64,
1003 stream_descriptor_SetDouble,
1004 stream_descriptor_SetGUID,
1005 stream_descriptor_SetString,
1006 stream_descriptor_SetBlob,
1007 stream_descriptor_SetUnknown,
1008 stream_descriptor_LockStore,
1009 stream_descriptor_UnlockStore,
1010 stream_descriptor_GetCount,
1011 stream_descriptor_GetItemByIndex,
1012 stream_descriptor_CopyAllItems,
1013 stream_descriptor_GetStreamIdentifier,
1014 stream_descriptor_GetMediaTypeHandler
1017 static HRESULT WINAPI mediatype_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, void **obj)
1019 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
1021 if (IsEqualIID(riid, &IID_IMFMediaTypeHandler) ||
1022 IsEqualIID(riid, &IID_IUnknown))
1024 *obj = iface;
1025 IMFMediaTypeHandler_AddRef(iface);
1026 return S_OK;
1029 WARN("Unsupported %s.\n", debugstr_guid(riid));
1030 *obj = NULL;
1031 return E_NOINTERFACE;
1034 static ULONG WINAPI mediatype_handler_AddRef(IMFMediaTypeHandler *iface)
1036 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1037 return IMFStreamDescriptor_AddRef(&stream_desc->IMFStreamDescriptor_iface);
1040 static ULONG WINAPI mediatype_handler_Release(IMFMediaTypeHandler *iface)
1042 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1043 return IMFStreamDescriptor_Release(&stream_desc->IMFStreamDescriptor_iface);
1046 static BOOL stream_descriptor_is_mediatype_supported(IMFMediaType *media_type, IMFMediaType *candidate)
1048 DWORD flags = 0;
1050 if (FAILED(IMFMediaType_IsEqual(media_type, candidate, &flags)))
1051 return FALSE;
1053 return (flags & (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES)) ==
1054 (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES);
1057 static HRESULT WINAPI mediatype_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, IMFMediaType *in_type,
1058 IMFMediaType **out_type)
1060 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1061 BOOL supported = FALSE;
1062 unsigned int i;
1064 TRACE("%p, %p, %p.\n", iface, in_type, out_type);
1066 if (!in_type)
1067 return E_POINTER;
1069 if (out_type)
1070 *out_type = NULL;
1072 EnterCriticalSection(&stream_desc->attributes.cs);
1074 supported = stream_desc->current_type && stream_descriptor_is_mediatype_supported(stream_desc->current_type, in_type);
1075 if (!supported)
1077 for (i = 0; i < stream_desc->media_types_count; ++i)
1079 if ((supported = stream_descriptor_is_mediatype_supported(stream_desc->media_types[i], in_type)))
1080 break;
1084 LeaveCriticalSection(&stream_desc->attributes.cs);
1086 return supported ? S_OK : MF_E_INVALIDMEDIATYPE;
1089 static HRESULT WINAPI mediatype_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count)
1091 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1093 TRACE("%p, %p.\n", iface, count);
1095 *count = stream_desc->media_types_count;
1097 return S_OK;
1100 static HRESULT WINAPI mediatype_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index,
1101 IMFMediaType **type)
1103 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1105 TRACE("%p, %u, %p.\n", iface, index, type);
1107 if (index >= stream_desc->media_types_count)
1108 return MF_E_NO_MORE_TYPES;
1110 if (stream_desc->media_types[index])
1112 *type = stream_desc->media_types[index];
1113 IMFMediaType_AddRef(*type);
1116 return stream_desc->media_types[index] ? S_OK : E_FAIL;
1119 static HRESULT WINAPI mediatype_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *type)
1121 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1123 TRACE("%p, %p.\n", iface, type);
1125 if (!type)
1126 return E_POINTER;
1128 EnterCriticalSection(&stream_desc->attributes.cs);
1129 if (stream_desc->current_type)
1130 IMFMediaType_Release(stream_desc->current_type);
1131 stream_desc->current_type = type;
1132 IMFMediaType_AddRef(stream_desc->current_type);
1133 LeaveCriticalSection(&stream_desc->attributes.cs);
1135 return S_OK;
1138 static HRESULT WINAPI mediatype_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **type)
1140 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1141 HRESULT hr = S_OK;
1143 TRACE("%p, %p.\n", iface, type);
1145 EnterCriticalSection(&stream_desc->attributes.cs);
1146 if (stream_desc->current_type)
1148 *type = stream_desc->current_type;
1149 IMFMediaType_AddRef(*type);
1151 else
1152 hr = MF_E_NOT_INITIALIZED;
1153 LeaveCriticalSection(&stream_desc->attributes.cs);
1155 return hr;
1158 static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type)
1160 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1161 HRESULT hr;
1163 TRACE("%p, %p.\n", iface, type);
1165 EnterCriticalSection(&stream_desc->attributes.cs);
1166 if (stream_desc->current_type)
1167 hr = IMFMediaType_GetGUID(stream_desc->current_type, &MF_MT_MAJOR_TYPE, type);
1168 else
1169 hr = MF_E_ATTRIBUTENOTFOUND;
1170 LeaveCriticalSection(&stream_desc->attributes.cs);
1172 return hr;
1175 static const IMFMediaTypeHandlerVtbl mediatypehandlervtbl =
1177 mediatype_handler_QueryInterface,
1178 mediatype_handler_AddRef,
1179 mediatype_handler_Release,
1180 mediatype_handler_IsMediaTypeSupported,
1181 mediatype_handler_GetMediaTypeCount,
1182 mediatype_handler_GetMediaTypeByIndex,
1183 mediatype_handler_SetCurrentMediaType,
1184 mediatype_handler_GetCurrentMediaType,
1185 mediatype_handler_GetMajorType,
1188 /***********************************************************************
1189 * MFCreateStreamDescriptor (mfplat.@)
1191 HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
1192 IMFMediaType **types, IMFStreamDescriptor **descriptor)
1194 struct stream_desc *object;
1195 unsigned int i;
1196 HRESULT hr;
1198 TRACE("%d, %d, %p, %p.\n", identifier, count, types, descriptor);
1200 if (!count)
1201 return E_INVALIDARG;
1203 object = heap_alloc_zero(sizeof(*object));
1204 if (!object)
1205 return E_OUTOFMEMORY;
1207 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
1209 heap_free(object);
1210 return hr;
1212 object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl;
1213 object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl;
1214 object->identifier = identifier;
1215 object->media_types = heap_alloc(count * sizeof(*object->media_types));
1216 if (!object->media_types)
1218 IMFStreamDescriptor_Release(&object->IMFStreamDescriptor_iface);
1219 return E_OUTOFMEMORY;
1221 for (i = 0; i < count; ++i)
1223 object->media_types[i] = types[i];
1224 if (object->media_types[i])
1225 IMFMediaType_AddRef(object->media_types[i]);
1227 object->media_types_count = count;
1229 *descriptor = &object->IMFStreamDescriptor_iface;
1231 return S_OK;
1234 static HRESULT WINAPI presentation_descriptor_QueryInterface(IMFPresentationDescriptor *iface, REFIID riid, void **out)
1236 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
1238 if (IsEqualIID(riid, &IID_IMFPresentationDescriptor) ||
1239 IsEqualIID(riid, &IID_IMFAttributes) ||
1240 IsEqualIID(riid, &IID_IUnknown))
1242 *out = iface;
1243 IMFPresentationDescriptor_AddRef(iface);
1244 return S_OK;
1247 WARN("Unsupported %s.\n", debugstr_guid(riid));
1248 *out = NULL;
1249 return E_NOINTERFACE;
1252 static ULONG WINAPI presentation_descriptor_AddRef(IMFPresentationDescriptor *iface)
1254 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1255 ULONG refcount = InterlockedIncrement(&presentation_desc->attributes.ref);
1257 TRACE("%p, refcount %u.\n", iface, refcount);
1259 return refcount;
1262 static ULONG WINAPI presentation_descriptor_Release(IMFPresentationDescriptor *iface)
1264 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1265 ULONG refcount = InterlockedDecrement(&presentation_desc->attributes.ref);
1266 unsigned int i;
1268 TRACE("%p, refcount %u.\n", iface, refcount);
1270 if (!refcount)
1272 for (i = 0; i < presentation_desc->count; ++i)
1274 if (presentation_desc->descriptors[i].descriptor)
1275 IMFStreamDescriptor_Release(presentation_desc->descriptors[i].descriptor);
1277 clear_attributes_object(&presentation_desc->attributes);
1278 heap_free(presentation_desc->descriptors);
1279 heap_free(presentation_desc);
1282 return refcount;
1285 static HRESULT WINAPI presentation_descriptor_GetItem(IMFPresentationDescriptor *iface, REFGUID key,
1286 PROPVARIANT *value)
1288 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1290 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1292 return attributes_GetItem(&presentation_desc->attributes, key, value);
1295 static HRESULT WINAPI presentation_descriptor_GetItemType(IMFPresentationDescriptor *iface, REFGUID key,
1296 MF_ATTRIBUTE_TYPE *type)
1298 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1300 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
1302 return attributes_GetItemType(&presentation_desc->attributes, key, type);
1305 static HRESULT WINAPI presentation_descriptor_CompareItem(IMFPresentationDescriptor *iface, REFGUID key,
1306 REFPROPVARIANT value, BOOL *result)
1308 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1310 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
1312 return attributes_CompareItem(&presentation_desc->attributes, key, value, result);
1315 static HRESULT WINAPI presentation_descriptor_Compare(IMFPresentationDescriptor *iface, IMFAttributes *attrs,
1316 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
1318 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1320 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
1322 return attributes_Compare(&presentation_desc->attributes, attrs, type, result);
1325 static HRESULT WINAPI presentation_descriptor_GetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *value)
1327 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1329 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1331 return attributes_GetUINT32(&presentation_desc->attributes, key, value);
1334 static HRESULT WINAPI presentation_descriptor_GetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 *value)
1336 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1338 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1340 return attributes_GetUINT64(&presentation_desc->attributes, key, value);
1343 static HRESULT WINAPI presentation_descriptor_GetDouble(IMFPresentationDescriptor *iface, REFGUID key, double *value)
1345 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1347 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1349 return attributes_GetDouble(&presentation_desc->attributes, key, value);
1352 static HRESULT WINAPI presentation_descriptor_GetGUID(IMFPresentationDescriptor *iface, REFGUID key, GUID *value)
1354 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1356 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1358 return attributes_GetGUID(&presentation_desc->attributes, key, value);
1361 static HRESULT WINAPI presentation_descriptor_GetStringLength(IMFPresentationDescriptor *iface, REFGUID key,
1362 UINT32 *length)
1364 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1366 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
1368 return attributes_GetStringLength(&presentation_desc->attributes, key, length);
1371 static HRESULT WINAPI presentation_descriptor_GetString(IMFPresentationDescriptor *iface, REFGUID key, WCHAR *value,
1372 UINT32 size, UINT32 *length)
1374 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1376 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
1378 return attributes_GetString(&presentation_desc->attributes, key, value, size, length);
1381 static HRESULT WINAPI presentation_descriptor_GetAllocatedString(IMFPresentationDescriptor *iface, REFGUID key,
1382 WCHAR **value, UINT32 *length)
1384 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1386 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
1388 return attributes_GetAllocatedString(&presentation_desc->attributes, key, value, length);
1391 static HRESULT WINAPI presentation_descriptor_GetBlobSize(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *size)
1393 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1395 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
1397 return attributes_GetBlobSize(&presentation_desc->attributes, key, size);
1400 static HRESULT WINAPI presentation_descriptor_GetBlob(IMFPresentationDescriptor *iface, REFGUID key, UINT8 *buf,
1401 UINT32 bufsize, UINT32 *blobsize)
1403 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1405 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
1407 return attributes_GetBlob(&presentation_desc->attributes, key, buf, bufsize, blobsize);
1410 static HRESULT WINAPI presentation_descriptor_GetAllocatedBlob(IMFPresentationDescriptor *iface, REFGUID key,
1411 UINT8 **buf, UINT32 *size)
1413 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1415 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
1417 return attributes_GetAllocatedBlob(&presentation_desc->attributes, key, buf, size);
1420 static HRESULT WINAPI presentation_descriptor_GetUnknown(IMFPresentationDescriptor *iface, REFGUID key,
1421 REFIID riid, void **out)
1423 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1425 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), out);
1427 return attributes_GetUnknown(&presentation_desc->attributes, key, riid, out);
1430 static HRESULT WINAPI presentation_descriptor_SetItem(IMFPresentationDescriptor *iface, REFGUID key,
1431 REFPROPVARIANT value)
1433 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1435 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
1437 return attributes_SetItem(&presentation_desc->attributes, key, value);
1440 static HRESULT WINAPI presentation_descriptor_DeleteItem(IMFPresentationDescriptor *iface, REFGUID key)
1442 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1444 TRACE("%p, %s.\n", iface, debugstr_attr(key));
1446 return attributes_DeleteItem(&presentation_desc->attributes, key);
1449 static HRESULT WINAPI presentation_descriptor_DeleteAllItems(IMFPresentationDescriptor *iface)
1451 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1453 TRACE("%p.\n", iface);
1455 return attributes_DeleteAllItems(&presentation_desc->attributes);
1458 static HRESULT WINAPI presentation_descriptor_SetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 value)
1460 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1462 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
1464 return attributes_SetUINT32(&presentation_desc->attributes, key, value);
1467 static HRESULT WINAPI presentation_descriptor_SetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 value)
1469 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1471 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
1473 return attributes_SetUINT64(&presentation_desc->attributes, key, value);
1476 static HRESULT WINAPI presentation_descriptor_SetDouble(IMFPresentationDescriptor *iface, REFGUID key, double value)
1478 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1480 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
1482 return attributes_SetDouble(&presentation_desc->attributes, key, value);
1485 static HRESULT WINAPI presentation_descriptor_SetGUID(IMFPresentationDescriptor *iface, REFGUID key, REFGUID value)
1487 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1489 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
1491 return attributes_SetGUID(&presentation_desc->attributes, key, value);
1494 static HRESULT WINAPI presentation_descriptor_SetString(IMFPresentationDescriptor *iface, REFGUID key,
1495 const WCHAR *value)
1497 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1499 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
1501 return attributes_SetString(&presentation_desc->attributes, key, value);
1504 static HRESULT WINAPI presentation_descriptor_SetBlob(IMFPresentationDescriptor *iface, REFGUID key, const UINT8 *buf,
1505 UINT32 size)
1507 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1509 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
1511 return attributes_SetBlob(&presentation_desc->attributes, key, buf, size);
1514 static HRESULT WINAPI presentation_descriptor_SetUnknown(IMFPresentationDescriptor *iface, REFGUID key,
1515 IUnknown *unknown)
1517 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1519 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
1521 return attributes_SetUnknown(&presentation_desc->attributes, key, unknown);
1524 static HRESULT WINAPI presentation_descriptor_LockStore(IMFPresentationDescriptor *iface)
1526 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1528 TRACE("%p.\n", iface);
1530 return attributes_LockStore(&presentation_desc->attributes);
1533 static HRESULT WINAPI presentation_descriptor_UnlockStore(IMFPresentationDescriptor *iface)
1535 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1537 TRACE("%p.\n", iface);
1539 return attributes_UnlockStore(&presentation_desc->attributes);
1542 static HRESULT WINAPI presentation_descriptor_GetCount(IMFPresentationDescriptor *iface, UINT32 *count)
1544 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1546 TRACE("%p, %p.\n", iface, count);
1548 return attributes_GetCount(&presentation_desc->attributes, count);
1551 static HRESULT WINAPI presentation_descriptor_GetItemByIndex(IMFPresentationDescriptor *iface, UINT32 index, GUID *key,
1552 PROPVARIANT *value)
1554 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1556 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
1558 return attributes_GetItemByIndex(&presentation_desc->attributes, index, key, value);
1561 static HRESULT WINAPI presentation_descriptor_CopyAllItems(IMFPresentationDescriptor *iface, IMFAttributes *dest)
1563 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1565 TRACE("%p, %p.\n", iface, dest);
1567 return attributes_CopyAllItems(&presentation_desc->attributes, dest);
1570 static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorCount(IMFPresentationDescriptor *iface, DWORD *count)
1572 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1574 TRACE("%p, %p.\n", iface, count);
1576 *count = presentation_desc->count;
1578 return S_OK;
1581 static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorByIndex(IMFPresentationDescriptor *iface, DWORD index,
1582 BOOL *selected, IMFStreamDescriptor **descriptor)
1584 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1586 TRACE("%p, %u, %p, %p.\n", iface, index, selected, descriptor);
1588 if (index >= presentation_desc->count)
1589 return E_INVALIDARG;
1591 EnterCriticalSection(&presentation_desc->attributes.cs);
1592 *selected = presentation_desc->descriptors[index].selected;
1593 LeaveCriticalSection(&presentation_desc->attributes.cs);
1595 *descriptor = presentation_desc->descriptors[index].descriptor;
1596 IMFStreamDescriptor_AddRef(*descriptor);
1598 return S_OK;
1601 static HRESULT WINAPI presentation_descriptor_SelectStream(IMFPresentationDescriptor *iface, DWORD index)
1603 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1605 TRACE("%p, %u.\n", iface, index);
1607 if (index >= presentation_desc->count)
1608 return E_INVALIDARG;
1610 EnterCriticalSection(&presentation_desc->attributes.cs);
1611 presentation_desc->descriptors[index].selected = TRUE;
1612 LeaveCriticalSection(&presentation_desc->attributes.cs);
1614 return S_OK;
1617 static HRESULT WINAPI presentation_descriptor_DeselectStream(IMFPresentationDescriptor *iface, DWORD index)
1619 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1621 TRACE("%p, %u.\n", iface, index);
1623 if (index >= presentation_desc->count)
1624 return E_INVALIDARG;
1626 EnterCriticalSection(&presentation_desc->attributes.cs);
1627 presentation_desc->descriptors[index].selected = FALSE;
1628 LeaveCriticalSection(&presentation_desc->attributes.cs);
1630 return S_OK;
1633 static HRESULT WINAPI presentation_descriptor_Clone(IMFPresentationDescriptor *iface,
1634 IMFPresentationDescriptor **descriptor)
1636 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
1637 struct presentation_desc *object;
1638 unsigned int i;
1640 TRACE("%p, %p.\n", iface, descriptor);
1642 object = heap_alloc_zero(sizeof(*object));
1643 if (!object)
1644 return E_OUTOFMEMORY;
1646 presentation_descriptor_init(object, presentation_desc->count);
1648 EnterCriticalSection(&presentation_desc->attributes.cs);
1650 for (i = 0; i < presentation_desc->count; ++i)
1652 object->descriptors[i] = presentation_desc->descriptors[i];
1653 IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor);
1656 attributes_CopyAllItems(&presentation_desc->attributes, (IMFAttributes *)&object->IMFPresentationDescriptor_iface);
1658 LeaveCriticalSection(&presentation_desc->attributes.cs);
1660 *descriptor = &object->IMFPresentationDescriptor_iface;
1662 return S_OK;
1665 static const IMFPresentationDescriptorVtbl presentationdescriptorvtbl =
1667 presentation_descriptor_QueryInterface,
1668 presentation_descriptor_AddRef,
1669 presentation_descriptor_Release,
1670 presentation_descriptor_GetItem,
1671 presentation_descriptor_GetItemType,
1672 presentation_descriptor_CompareItem,
1673 presentation_descriptor_Compare,
1674 presentation_descriptor_GetUINT32,
1675 presentation_descriptor_GetUINT64,
1676 presentation_descriptor_GetDouble,
1677 presentation_descriptor_GetGUID,
1678 presentation_descriptor_GetStringLength,
1679 presentation_descriptor_GetString,
1680 presentation_descriptor_GetAllocatedString,
1681 presentation_descriptor_GetBlobSize,
1682 presentation_descriptor_GetBlob,
1683 presentation_descriptor_GetAllocatedBlob,
1684 presentation_descriptor_GetUnknown,
1685 presentation_descriptor_SetItem,
1686 presentation_descriptor_DeleteItem,
1687 presentation_descriptor_DeleteAllItems,
1688 presentation_descriptor_SetUINT32,
1689 presentation_descriptor_SetUINT64,
1690 presentation_descriptor_SetDouble,
1691 presentation_descriptor_SetGUID,
1692 presentation_descriptor_SetString,
1693 presentation_descriptor_SetBlob,
1694 presentation_descriptor_SetUnknown,
1695 presentation_descriptor_LockStore,
1696 presentation_descriptor_UnlockStore,
1697 presentation_descriptor_GetCount,
1698 presentation_descriptor_GetItemByIndex,
1699 presentation_descriptor_CopyAllItems,
1700 presentation_descriptor_GetStreamDescriptorCount,
1701 presentation_descriptor_GetStreamDescriptorByIndex,
1702 presentation_descriptor_SelectStream,
1703 presentation_descriptor_DeselectStream,
1704 presentation_descriptor_Clone,
1707 static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count)
1709 HRESULT hr;
1711 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
1712 return hr;
1713 object->IMFPresentationDescriptor_iface.lpVtbl = &presentationdescriptorvtbl;
1714 object->descriptors = heap_alloc_zero(count * sizeof(*object->descriptors));
1715 if (!object->descriptors)
1717 IMFPresentationDescriptor_Release(&object->IMFPresentationDescriptor_iface);
1718 return E_OUTOFMEMORY;
1720 object->count = count;
1722 return S_OK;
1725 /***********************************************************************
1726 * MFCreatePresentationDescriptor (mfplat.@)
1728 HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor **descriptors,
1729 IMFPresentationDescriptor **out)
1731 struct presentation_desc *object;
1732 unsigned int i;
1733 HRESULT hr;
1735 TRACE("%u, %p, %p.\n", count, descriptors, out);
1737 if (!count)
1738 return E_INVALIDARG;
1740 for (i = 0; i < count; ++i)
1742 if (!descriptors[i])
1743 return E_INVALIDARG;
1746 object = heap_alloc_zero(sizeof(*object));
1747 if (!object)
1748 return E_OUTOFMEMORY;
1750 if (FAILED(hr = presentation_descriptor_init(object, count)))
1752 heap_free(object);
1753 return hr;
1756 for (i = 0; i < count; ++i)
1758 object->descriptors[i].descriptor = descriptors[i];
1759 IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor);
1762 *out = &object->IMFPresentationDescriptor_iface;
1764 return S_OK;
1767 struct uncompressed_video_format
1769 const GUID *subtype;
1770 unsigned char bytes_per_pixel;
1771 unsigned char alignment;
1772 unsigned char bottom_up;
1773 unsigned char yuv;
1776 static int __cdecl uncompressed_video_format_compare(const void *a, const void *b)
1778 const GUID *guid = a;
1779 const struct uncompressed_video_format *format = b;
1780 return memcmp(guid, format->subtype, sizeof(*guid));
1783 static const struct uncompressed_video_format video_formats[] =
1785 { &MFVideoFormat_RGB24, 4, 3, 1, 0 },
1786 { &MFVideoFormat_ARGB32, 4, 3, 1, 0 },
1787 { &MFVideoFormat_RGB32, 4, 3, 1, 0 },
1788 { &MFVideoFormat_RGB565, 2, 3, 1, 0 },
1789 { &MFVideoFormat_RGB555, 2, 3, 1, 0 },
1790 { &MFVideoFormat_A2R10G10B10, 4, 3, 1, 0 },
1791 { &MFVideoFormat_RGB8, 1, 3, 1, 0 },
1792 { &MFVideoFormat_L8, 1, 3, 1, 0 },
1793 { &MFVideoFormat_AYUV, 4, 3, 0, 1 },
1794 { &MFVideoFormat_I420, 1, 0, 0, 1 },
1795 { &MFVideoFormat_IMC1, 2, 3, 0, 1 },
1796 { &MFVideoFormat_IMC2, 1, 0, 0, 1 },
1797 { &MFVideoFormat_IMC3, 2, 3, 0, 1 },
1798 { &MFVideoFormat_IMC4, 1, 0, 0, 1 },
1799 { &MFVideoFormat_NV12, 1, 0, 0, 1 },
1800 { &MFVideoFormat_D16, 2, 3, 0, 0 },
1801 { &MFVideoFormat_L16, 2, 3, 0, 0 },
1802 { &MFVideoFormat_UYVY, 2, 0, 0, 1 },
1803 { &MFVideoFormat_YUY2, 2, 0, 0, 1 },
1804 { &MFVideoFormat_YV12, 1, 0, 0, 1 },
1805 { &MFVideoFormat_A16B16G16R16F, 8, 3, 1, 0 },
1808 static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype)
1810 return bsearch(subtype, video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats),
1811 uncompressed_video_format_compare);
1814 static unsigned int mf_get_stride_for_format(const struct uncompressed_video_format *format, unsigned int width)
1816 return (width * format->bytes_per_pixel + format->alignment) & ~format->alignment;
1819 unsigned int mf_format_get_stride(const GUID *subtype, unsigned int width, BOOL *is_yuv)
1821 struct uncompressed_video_format *format = mf_get_video_format(subtype);
1823 if (format)
1825 *is_yuv = format->yuv;
1826 return mf_get_stride_for_format(format, width);
1829 return 0;
1832 /***********************************************************************
1833 * MFGetStrideForBitmapInfoHeader (mfplat.@)
1835 HRESULT WINAPI MFGetStrideForBitmapInfoHeader(DWORD fourcc, DWORD width, LONG *stride)
1837 struct uncompressed_video_format *format;
1838 GUID subtype;
1840 TRACE("%s, %u, %p.\n", debugstr_fourcc(fourcc), width, stride);
1842 memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
1843 subtype.Data1 = fourcc;
1845 if (!(format = mf_get_video_format(&subtype)))
1847 *stride = 0;
1848 return MF_E_INVALIDMEDIATYPE;
1851 *stride = mf_get_stride_for_format(format, width);
1852 if (format->bottom_up)
1853 *stride *= -1;
1855 return S_OK;
1858 /***********************************************************************
1859 * MFCalculateImageSize (mfplat.@)
1861 HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size)
1863 struct uncompressed_video_format *format;
1864 unsigned int stride;
1866 TRACE("%s, %u, %u, %p.\n", debugstr_mf_guid(subtype), width, height, size);
1868 if (!(format = mf_get_video_format(subtype)))
1870 *size = 0;
1871 return E_INVALIDARG;
1874 switch (subtype->Data1)
1876 case MAKEFOURCC('I','M','C','2'):
1877 case MAKEFOURCC('I','M','C','4'):
1878 case MAKEFOURCC('N','V','1','2'):
1879 case MAKEFOURCC('Y','V','1','2'):
1880 case MAKEFOURCC('I','4','2','0'):
1881 /* 2 x 2 block, interleaving UV for half the height */
1882 *size = ((width + 1) & ~1) * height * 3 / 2;
1883 break;
1884 case D3DFMT_L8:
1885 case D3DFMT_L16:
1886 case D3DFMT_D16:
1887 *size = width * format->bytes_per_pixel * height;
1888 break;
1889 default:
1890 stride = mf_get_stride_for_format(format, width);
1891 *size = stride * height;
1894 return S_OK;
1897 /***********************************************************************
1898 * MFGetPlaneSize (mfplat.@)
1900 HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *size)
1902 struct uncompressed_video_format *format;
1903 unsigned int stride;
1904 GUID subtype;
1906 TRACE("%s, %u, %u, %p.\n", debugstr_fourcc(fourcc), width, height, size);
1908 memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
1909 subtype.Data1 = fourcc;
1911 if (!(format = mf_get_video_format(&subtype)))
1912 return MF_E_INVALIDMEDIATYPE;
1914 stride = mf_get_stride_for_format(format, width);
1916 switch (fourcc)
1918 case MAKEFOURCC('I','M','C','2'):
1919 case MAKEFOURCC('I','M','C','4'):
1920 case MAKEFOURCC('N','V','1','2'):
1921 case MAKEFOURCC('Y','V','1','2'):
1922 case MAKEFOURCC('I','4','2','0'):
1923 *size = stride * height * 3 / 2;
1924 break;
1925 default:
1926 *size = stride * height;
1929 return S_OK;
1932 /***********************************************************************
1933 * MFCompareFullToPartialMediaType (mfplat.@)
1935 BOOL WINAPI MFCompareFullToPartialMediaType(IMFMediaType *full_type, IMFMediaType *partial_type)
1937 BOOL result;
1938 GUID major;
1940 TRACE("%p, %p.\n", full_type, partial_type);
1942 if (FAILED(IMFMediaType_GetMajorType(partial_type, &major)))
1943 return FALSE;
1945 if (FAILED(IMFMediaType_Compare(partial_type, (IMFAttributes *)full_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result)))
1946 return FALSE;
1948 return result;
1951 /***********************************************************************
1952 * MFWrapMediaType (mfplat.@)
1954 HRESULT WINAPI MFWrapMediaType(IMFMediaType *original, REFGUID major, REFGUID subtype, IMFMediaType **ret)
1956 IMFMediaType *mediatype;
1957 UINT8 *buffer;
1958 UINT32 size;
1959 HRESULT hr;
1961 TRACE("%p, %s, %s, %p.\n", original, debugstr_guid(major), debugstr_guid(subtype), ret);
1963 if (FAILED(hr = MFGetAttributesAsBlobSize((IMFAttributes *)original, &size)))
1964 return hr;
1966 if (!(buffer = heap_alloc(size)))
1967 return E_OUTOFMEMORY;
1969 if (FAILED(hr = MFGetAttributesAsBlob((IMFAttributes *)original, buffer, size)))
1970 goto failed;
1972 if (FAILED(hr = MFCreateMediaType(&mediatype)))
1973 goto failed;
1975 if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major)))
1976 goto failed;
1978 if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, subtype)))
1979 goto failed;
1981 if (FAILED(hr = IMFMediaType_SetBlob(mediatype, &MF_MT_WRAPPED_TYPE, buffer, size)))
1982 goto failed;
1984 *ret = mediatype;
1986 failed:
1987 heap_free(buffer);
1989 return hr;
1992 /***********************************************************************
1993 * MFUnwrapMediaType (mfplat.@)
1995 HRESULT WINAPI MFUnwrapMediaType(IMFMediaType *wrapper, IMFMediaType **ret)
1997 IMFMediaType *mediatype;
1998 UINT8 *buffer;
1999 UINT32 size;
2000 HRESULT hr;
2002 TRACE("%p, %p.\n", wrapper, ret);
2004 if (FAILED(hr = MFCreateMediaType(&mediatype)))
2005 return hr;
2007 if (FAILED(hr = IMFMediaType_GetAllocatedBlob(wrapper, &MF_MT_WRAPPED_TYPE, &buffer, &size)))
2009 IMFMediaType_Release(mediatype);
2010 return hr;
2013 hr = MFInitAttributesFromBlob((IMFAttributes *)mediatype, buffer, size);
2014 CoTaskMemFree(buffer);
2015 if (FAILED(hr))
2016 return hr;
2018 *ret = mediatype;
2020 return S_OK;
2023 /***********************************************************************
2024 * MFCreateWaveFormatExFromMFMediaType (mfplat.@)
2026 HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVEFORMATEX **ret_format,
2027 UINT32 *size, UINT32 flags)
2029 WAVEFORMATEXTENSIBLE *format_ext = NULL;
2030 WAVEFORMATEX *format;
2031 GUID major, subtype;
2032 UINT32 value;
2033 HRESULT hr;
2035 TRACE("%p, %p, %p, %#x.\n", mediatype, ret_format, size, flags);
2037 if (FAILED(hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &major)))
2038 return hr;
2040 if (FAILED(hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &subtype)))
2041 return hr;
2043 if (!IsEqualGUID(&major, &MFMediaType_Audio))
2044 return E_INVALIDARG;
2046 if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM))
2048 FIXME("Unsupported audio format %s.\n", debugstr_guid(&subtype));
2049 return E_NOTIMPL;
2052 /* FIXME: probably WAVE_FORMAT_MPEG/WAVE_FORMAT_MPEGLAYER3 should be handled separately. */
2053 if (flags == MFWaveFormatExConvertFlag_ForceExtensible)
2055 format_ext = CoTaskMemAlloc(sizeof(*format_ext));
2056 *size = sizeof(*format_ext);
2057 format = (WAVEFORMATEX *)format_ext;
2059 else
2061 format = CoTaskMemAlloc(sizeof(*format));
2062 *size = sizeof(*format);
2065 if (!format)
2066 return E_OUTOFMEMORY;
2068 memset(format, 0, *size);
2070 format->wFormatTag = format_ext ? WAVE_FORMAT_EXTENSIBLE : WAVE_FORMAT_PCM;
2072 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value)))
2073 format->nChannels = value;
2074 IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &format->nSamplesPerSec);
2075 IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &format->nAvgBytesPerSec);
2076 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value)))
2077 format->nBlockAlign = value;
2078 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value)))
2079 format->wBitsPerSample = value;
2080 if (format_ext)
2082 format->cbSize = sizeof(*format_ext) - sizeof(*format);
2084 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value)))
2085 format_ext->Samples.wSamplesPerBlock = value;
2087 IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &format_ext->dwChannelMask);
2088 memcpy(&format_ext->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(format_ext->SubFormat));
2091 *ret_format = format;
2093 return S_OK;
2096 static void mediatype_set_uint32(IMFMediaType *mediatype, const GUID *attr, unsigned int value, HRESULT *hr)
2098 if (SUCCEEDED(*hr))
2099 *hr = IMFMediaType_SetUINT32(mediatype, attr, value);
2102 static void mediatype_set_guid(IMFMediaType *mediatype, const GUID *attr, const GUID *value, HRESULT *hr)
2104 if (SUCCEEDED(*hr))
2105 *hr = IMFMediaType_SetGUID(mediatype, attr, value);
2108 /***********************************************************************
2109 * MFInitMediaTypeFromWaveFormatEx (mfplat.@)
2111 HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size)
2113 const WAVEFORMATEXTENSIBLE *wfex = (const WAVEFORMATEXTENSIBLE *)format;
2114 GUID subtype;
2115 HRESULT hr;
2117 TRACE("%p, %p, %u.\n", mediatype, format, size);
2119 if (!mediatype || !format)
2120 return E_POINTER;
2122 if (format->cbSize && format->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX))
2123 return E_INVALIDARG;
2125 if (format->cbSize + sizeof(*format) > size)
2126 return E_INVALIDARG;
2128 hr = IMFMediaType_DeleteAllItems(mediatype);
2130 mediatype_set_guid(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio, &hr);
2132 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
2134 memcpy(&subtype, &wfex->SubFormat, sizeof(subtype));
2136 if (wfex->dwChannelMask)
2137 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, wfex->dwChannelMask, &hr);
2139 if (format->wBitsPerSample && wfex->Samples.wValidBitsPerSample)
2140 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, wfex->Samples.wValidBitsPerSample, &hr);
2142 else
2144 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
2145 subtype.Data1 = format->wFormatTag;
2147 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr);
2149 mediatype_set_guid(mediatype, &MF_MT_SUBTYPE, &subtype, &hr);
2151 if (format->nChannels)
2152 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, format->nChannels, &hr);
2154 if (format->nSamplesPerSec)
2155 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->nSamplesPerSec, &hr);
2157 if (format->nAvgBytesPerSec)
2158 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, format->nAvgBytesPerSec, &hr);
2160 if (format->nBlockAlign)
2161 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->nBlockAlign, &hr);
2163 if (format->wBitsPerSample)
2164 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, format->wBitsPerSample, &hr);
2166 if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) ||
2167 IsEqualGUID(&subtype, &MFAudioFormat_Float))
2169 mediatype_set_uint32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr);
2172 return hr;