mfplat/mediatype: Implement MF_MT_FRAME_RATE from VIDEOINFOHEADER2.
[wine.git] / dlls / mfplat / mediatype.c
blob96d9a07973e5f3ec0e12b21fbcfe4e6e58b09e9d
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"
22 #include <math.h>
24 #include "dxva2api.h"
25 #include "uuids.h"
26 #include "strmif.h"
27 #include "initguid.h"
28 #include "dvdmedia.h"
29 #include "ks.h"
30 #include "ksmedia.h"
31 #include "amvideo.h"
32 #include "wmcodecdsp.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
36 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
38 DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB1, D3DFMT_A1);
39 DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB4, MAKEFOURCC('4','P','x','x'));
40 DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB1555, D3DFMT_A1R5G5B5);
41 DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB4444, D3DFMT_A4R4G4B4);
42 /* SDK MFVideoFormat_A2R10G10B10 uses D3DFMT_A2B10G10R10, let's name it the other way */
43 DEFINE_MEDIATYPE_GUID(MFVideoFormat_A2B10G10R10, D3DFMT_A2R10G10B10);
45 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
46 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
47 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
48 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
50 static const UINT32 default_channel_mask[7] =
53 SPEAKER_FRONT_LEFT,
54 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
55 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
56 KSAUDIO_SPEAKER_QUAD,
57 KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER,
58 KSAUDIO_SPEAKER_5POINT1,
61 static GUID get_am_subtype_for_mf_subtype(GUID subtype)
63 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB1))
64 return MEDIASUBTYPE_RGB1;
65 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB4))
66 return MEDIASUBTYPE_RGB4;
67 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB8))
68 return MEDIASUBTYPE_RGB8;
69 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB555))
70 return MEDIASUBTYPE_RGB555;
71 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB565))
72 return MEDIASUBTYPE_RGB565;
73 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB24))
74 return MEDIASUBTYPE_RGB24;
75 if (IsEqualGUID(&subtype, &MFVideoFormat_RGB32))
76 return MEDIASUBTYPE_RGB32;
77 if (IsEqualGUID(&subtype, &MFVideoFormat_ARGB1555))
78 return MEDIASUBTYPE_ARGB1555;
79 if (IsEqualGUID(&subtype, &MFVideoFormat_ARGB4444))
80 return MEDIASUBTYPE_ARGB4444;
81 if (IsEqualGUID(&subtype, &MFVideoFormat_ARGB32))
82 return MEDIASUBTYPE_ARGB32;
83 if (IsEqualGUID(&subtype, &MFVideoFormat_A2B10G10R10))
84 return MEDIASUBTYPE_A2R10G10B10;
85 if (IsEqualGUID(&subtype, &MFVideoFormat_A2R10G10B10))
86 return MEDIASUBTYPE_A2B10G10R10;
87 return subtype;
90 struct media_type
92 struct attributes attributes;
93 IMFMediaType IMFMediaType_iface;
94 IMFVideoMediaType IMFVideoMediaType_iface;
95 IMFAudioMediaType IMFAudioMediaType_iface;
96 MFVIDEOFORMAT *video_format;
97 WAVEFORMATEX *audio_format;
100 struct stream_desc
102 struct attributes attributes;
103 IMFStreamDescriptor IMFStreamDescriptor_iface;
104 IMFMediaTypeHandler IMFMediaTypeHandler_iface;
105 DWORD identifier;
106 IMFMediaType **media_types;
107 unsigned int media_types_count;
108 IMFMediaType *current_type;
111 struct presentation_desc_entry
113 IMFStreamDescriptor *descriptor;
114 BOOL selected;
117 struct presentation_desc
119 struct attributes attributes;
120 IMFPresentationDescriptor IMFPresentationDescriptor_iface;
121 struct presentation_desc_entry *descriptors;
122 unsigned int count;
125 static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count);
127 static struct media_type *impl_from_IMFMediaType(IMFMediaType *iface)
129 return CONTAINING_RECORD(iface, struct media_type, IMFMediaType_iface);
132 static struct media_type *impl_from_IMFVideoMediaType(IMFVideoMediaType *iface)
134 return CONTAINING_RECORD(iface, struct media_type, IMFVideoMediaType_iface);
137 static struct media_type *impl_from_IMFAudioMediaType(IMFAudioMediaType *iface)
139 return CONTAINING_RECORD(iface, struct media_type, IMFAudioMediaType_iface);
142 static inline struct stream_desc *impl_from_IMFStreamDescriptor(IMFStreamDescriptor *iface)
144 return CONTAINING_RECORD(iface, struct stream_desc, IMFStreamDescriptor_iface);
147 static struct stream_desc *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface)
149 return CONTAINING_RECORD(iface, struct stream_desc, IMFMediaTypeHandler_iface);
152 static struct presentation_desc *impl_from_IMFPresentationDescriptor(IMFPresentationDescriptor *iface)
154 return CONTAINING_RECORD(iface, struct presentation_desc, IMFPresentationDescriptor_iface);
157 static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out)
159 struct media_type *media_type = impl_from_IMFMediaType(iface);
160 GUID major = { 0 };
162 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
164 attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, &major);
166 if (IsEqualGUID(&major, &MFMediaType_Video) && IsEqualIID(riid, &IID_IMFVideoMediaType))
168 *out = &media_type->IMFVideoMediaType_iface;
170 else if (IsEqualGUID(&major, &MFMediaType_Audio) && IsEqualIID(riid, &IID_IMFAudioMediaType))
172 *out = &media_type->IMFAudioMediaType_iface;
174 else if (IsEqualIID(riid, &IID_IMFMediaType) ||
175 IsEqualIID(riid, &IID_IMFAttributes) ||
176 IsEqualIID(riid, &IID_IUnknown))
178 *out = &media_type->IMFMediaType_iface;
180 else
182 WARN("Unsupported %s.\n", debugstr_guid(riid));
183 *out = NULL;
184 return E_NOINTERFACE;
187 IUnknown_AddRef((IUnknown *)*out);
188 return S_OK;
191 static ULONG WINAPI mediatype_AddRef(IMFMediaType *iface)
193 struct media_type *media_type = impl_from_IMFMediaType(iface);
194 ULONG refcount = InterlockedIncrement(&media_type->attributes.ref);
196 TRACE("%p, refcount %lu.\n", iface, refcount);
198 return refcount;
201 static ULONG WINAPI mediatype_Release(IMFMediaType *iface)
203 struct media_type *media_type = impl_from_IMFMediaType(iface);
204 ULONG refcount = InterlockedDecrement(&media_type->attributes.ref);
206 TRACE("%p, refcount %lu.\n", iface, refcount);
208 if (!refcount)
210 clear_attributes_object(&media_type->attributes);
211 CoTaskMemFree(media_type->video_format);
212 CoTaskMemFree(media_type->audio_format);
213 free(media_type);
216 return refcount;
219 static HRESULT WINAPI mediatype_GetItem(IMFMediaType *iface, REFGUID key, PROPVARIANT *value)
221 struct media_type *media_type = impl_from_IMFMediaType(iface);
223 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
225 return attributes_GetItem(&media_type->attributes, key, value);
228 static HRESULT WINAPI mediatype_GetItemType(IMFMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
230 struct media_type *media_type = impl_from_IMFMediaType(iface);
232 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
234 return attributes_GetItemType(&media_type->attributes, key, type);
237 static HRESULT WINAPI mediatype_CompareItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
239 struct media_type *media_type = impl_from_IMFMediaType(iface);
241 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
243 return attributes_CompareItem(&media_type->attributes, key, value, result);
246 static HRESULT WINAPI mediatype_Compare(IMFMediaType *iface, IMFAttributes *attrs, MF_ATTRIBUTES_MATCH_TYPE type,
247 BOOL *result)
249 struct media_type *media_type = impl_from_IMFMediaType(iface);
251 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
253 return attributes_Compare(&media_type->attributes, attrs, type, result);
256 static HRESULT WINAPI mediatype_GetUINT32(IMFMediaType *iface, REFGUID key, UINT32 *value)
258 struct media_type *media_type = impl_from_IMFMediaType(iface);
260 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
262 return attributes_GetUINT32(&media_type->attributes, key, value);
265 static HRESULT WINAPI mediatype_GetUINT64(IMFMediaType *iface, REFGUID key, UINT64 *value)
267 struct media_type *media_type = impl_from_IMFMediaType(iface);
269 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
271 return attributes_GetUINT64(&media_type->attributes, key, value);
274 static HRESULT WINAPI mediatype_GetDouble(IMFMediaType *iface, REFGUID key, double *value)
276 struct media_type *media_type = impl_from_IMFMediaType(iface);
278 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
280 return attributes_GetDouble(&media_type->attributes, key, value);
283 static HRESULT WINAPI mediatype_GetGUID(IMFMediaType *iface, REFGUID key, GUID *value)
285 struct media_type *media_type = impl_from_IMFMediaType(iface);
287 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
289 return attributes_GetGUID(&media_type->attributes, key, value);
292 static HRESULT WINAPI mediatype_GetStringLength(IMFMediaType *iface, REFGUID key, UINT32 *length)
294 struct media_type *media_type = impl_from_IMFMediaType(iface);
296 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
298 return attributes_GetStringLength(&media_type->attributes, key, length);
301 static HRESULT WINAPI mediatype_GetString(IMFMediaType *iface, REFGUID key, WCHAR *value,
302 UINT32 size, UINT32 *length)
304 struct media_type *media_type = impl_from_IMFMediaType(iface);
306 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
308 return attributes_GetString(&media_type->attributes, key, value, size, length);
311 static HRESULT WINAPI mediatype_GetAllocatedString(IMFMediaType *iface, REFGUID key,
312 WCHAR **value, UINT32 *length)
314 struct media_type *media_type = impl_from_IMFMediaType(iface);
316 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
318 return attributes_GetAllocatedString(&media_type->attributes, key, value, length);
321 static HRESULT WINAPI mediatype_GetBlobSize(IMFMediaType *iface, REFGUID key, UINT32 *size)
323 struct media_type *media_type = impl_from_IMFMediaType(iface);
325 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
327 return attributes_GetBlobSize(&media_type->attributes, key, size);
330 static HRESULT WINAPI mediatype_GetBlob(IMFMediaType *iface, REFGUID key, UINT8 *buf,
331 UINT32 bufsize, UINT32 *blobsize)
333 struct media_type *media_type = impl_from_IMFMediaType(iface);
335 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
337 return attributes_GetBlob(&media_type->attributes, key, buf, bufsize, blobsize);
340 static HRESULT WINAPI mediatype_GetAllocatedBlob(IMFMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size)
342 struct media_type *media_type = impl_from_IMFMediaType(iface);
344 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
346 return attributes_GetAllocatedBlob(&media_type->attributes, key, buf, size);
349 static HRESULT WINAPI mediatype_GetUnknown(IMFMediaType *iface, REFGUID key, REFIID riid, void **obj)
351 struct media_type *media_type = impl_from_IMFMediaType(iface);
353 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), obj);
355 return attributes_GetUnknown(&media_type->attributes, key, riid, obj);
358 static HRESULT WINAPI mediatype_SetItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value)
360 struct media_type *media_type = impl_from_IMFMediaType(iface);
362 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
364 return attributes_SetItem(&media_type->attributes, key, value);
367 static HRESULT WINAPI mediatype_DeleteItem(IMFMediaType *iface, REFGUID key)
369 struct media_type *media_type = impl_from_IMFMediaType(iface);
371 TRACE("%p, %s.\n", iface, debugstr_attr(key));
373 return attributes_DeleteItem(&media_type->attributes, key);
376 static HRESULT WINAPI mediatype_DeleteAllItems(IMFMediaType *iface)
378 struct media_type *media_type = impl_from_IMFMediaType(iface);
380 TRACE("%p.\n", iface);
382 return attributes_DeleteAllItems(&media_type->attributes);
385 static HRESULT WINAPI mediatype_SetUINT32(IMFMediaType *iface, REFGUID key, UINT32 value)
387 struct media_type *media_type = impl_from_IMFMediaType(iface);
389 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
391 return attributes_SetUINT32(&media_type->attributes, key, value);
394 static HRESULT WINAPI mediatype_SetUINT64(IMFMediaType *iface, REFGUID key, UINT64 value)
396 struct media_type *media_type = impl_from_IMFMediaType(iface);
398 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
400 return attributes_SetUINT64(&media_type->attributes, key, value);
403 static HRESULT WINAPI mediatype_SetDouble(IMFMediaType *iface, REFGUID key, double value)
405 struct media_type *media_type = impl_from_IMFMediaType(iface);
407 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
409 return attributes_SetDouble(&media_type->attributes, key, value);
412 static HRESULT WINAPI mediatype_SetGUID(IMFMediaType *iface, REFGUID key, REFGUID value)
414 struct media_type *media_type = impl_from_IMFMediaType(iface);
416 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
418 return attributes_SetGUID(&media_type->attributes, key, value);
421 static HRESULT WINAPI mediatype_SetString(IMFMediaType *iface, REFGUID key, const WCHAR *value)
423 struct media_type *media_type = impl_from_IMFMediaType(iface);
425 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
427 return attributes_SetString(&media_type->attributes, key, value);
430 static HRESULT WINAPI mediatype_SetBlob(IMFMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size)
432 struct media_type *media_type = impl_from_IMFMediaType(iface);
434 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
436 return attributes_SetBlob(&media_type->attributes, key, buf, size);
439 static HRESULT WINAPI mediatype_SetUnknown(IMFMediaType *iface, REFGUID key, IUnknown *unknown)
441 struct media_type *media_type = impl_from_IMFMediaType(iface);
443 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
445 return attributes_SetUnknown(&media_type->attributes, key, unknown);
448 static HRESULT WINAPI mediatype_LockStore(IMFMediaType *iface)
450 struct media_type *media_type = impl_from_IMFMediaType(iface);
452 TRACE("%p.\n", iface);
454 return attributes_LockStore(&media_type->attributes);
457 static HRESULT WINAPI mediatype_UnlockStore(IMFMediaType *iface)
459 struct media_type *media_type = impl_from_IMFMediaType(iface);
461 TRACE("%p.\n", iface);
463 return attributes_UnlockStore(&media_type->attributes);
466 static HRESULT WINAPI mediatype_GetCount(IMFMediaType *iface, UINT32 *count)
468 struct media_type *media_type = impl_from_IMFMediaType(iface);
470 TRACE("%p, %p.\n", iface, count);
472 return attributes_GetCount(&media_type->attributes, count);
475 static HRESULT WINAPI mediatype_GetItemByIndex(IMFMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value)
477 struct media_type *media_type = impl_from_IMFMediaType(iface);
479 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
481 return attributes_GetItemByIndex(&media_type->attributes, index, key, value);
484 static HRESULT WINAPI mediatype_CopyAllItems(IMFMediaType *iface, IMFAttributes *dest)
486 struct media_type *media_type = impl_from_IMFMediaType(iface);
488 TRACE("%p, %p.\n", iface, dest);
490 return attributes_CopyAllItems(&media_type->attributes, dest);
493 static HRESULT WINAPI mediatype_GetMajorType(IMFMediaType *iface, GUID *guid)
495 struct media_type *media_type = impl_from_IMFMediaType(iface);
497 TRACE("%p, %p.\n", iface, guid);
499 return attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, guid);
502 static HRESULT mediatype_is_compressed(struct media_type *media_type, BOOL *compressed)
504 UINT32 value;
506 if (FAILED(attributes_GetUINT32(&media_type->attributes, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value)))
508 value = 0;
511 *compressed = !value;
513 return S_OK;
516 static HRESULT WINAPI mediatype_IsCompressedFormat(IMFMediaType *iface, BOOL *compressed)
518 struct media_type *media_type = impl_from_IMFMediaType(iface);
520 TRACE("%p, %p.\n", iface, compressed);
522 return mediatype_is_compressed(media_type, compressed);
525 static HRESULT media_type_is_equal(struct media_type *media_type, IMFMediaType *type, DWORD *flags)
527 const DWORD full_equality_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES |
528 MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA;
529 struct comparand
531 IMFAttributes *type;
532 PROPVARIANT value;
533 UINT32 count;
534 GUID guid;
535 HRESULT hr;
536 } left, right, swp;
537 unsigned int i;
538 BOOL result;
540 *flags = 0;
542 left.type = &media_type->attributes.IMFAttributes_iface;
543 right.type = (IMFAttributes *)type;
545 if (FAILED(IMFAttributes_GetGUID(left.type, &MF_MT_MAJOR_TYPE, &left.guid)))
546 return E_INVALIDARG;
548 if (FAILED(IMFAttributes_GetGUID(right.type, &MF_MT_MAJOR_TYPE, &right.guid)))
549 return E_INVALIDARG;
551 if (IsEqualGUID(&left.guid, &right.guid))
552 *flags |= MF_MEDIATYPE_EQUAL_MAJOR_TYPES;
554 /* Subtypes equal or both missing. */
555 left.hr = IMFAttributes_GetGUID(left.type, &MF_MT_SUBTYPE, &left.guid);
556 right.hr = IMFAttributes_GetGUID(right.type, &MF_MT_SUBTYPE, &right.guid);
558 if ((SUCCEEDED(left.hr) && SUCCEEDED(right.hr) && IsEqualGUID(&left.guid, &right.guid)) ||
559 (FAILED(left.hr) && FAILED(right.hr)))
561 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_TYPES;
564 /* Format data */
565 IMFAttributes_GetCount(left.type, &left.count);
566 IMFAttributes_GetCount(right.type, &right.count);
568 if (right.count < left.count)
570 swp = left;
571 left = right;
572 right = swp;
575 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_DATA;
577 for (i = 0; i < left.count; ++i)
579 PROPVARIANT value;
580 GUID key;
582 if (SUCCEEDED(IMFAttributes_GetItemByIndex(left.type, i, &key, &value)))
584 if (IsEqualGUID(&key, &MF_MT_USER_DATA) ||
585 IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MIN) ||
586 IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MAX))
588 PropVariantClear(&value);
589 continue;
592 result = FALSE;
593 IMFAttributes_CompareItem(right.type, &key, &value, &result);
594 PropVariantClear(&value);
595 if (!result)
597 *flags &= ~MF_MEDIATYPE_EQUAL_FORMAT_DATA;
598 break;
603 /* User data */
604 PropVariantInit(&left.value);
605 left.hr = IMFAttributes_GetItem(left.type, &MF_MT_USER_DATA, &left.value);
606 PropVariantInit(&right.value);
607 right.hr = IMFAttributes_GetItem(right.type, &MF_MT_USER_DATA, &right.value);
609 /* Compare user data if both types have it, otherwise simply check if both don't. */
610 if (SUCCEEDED(left.hr) && SUCCEEDED(right.hr))
612 result = FALSE;
613 IMFAttributes_CompareItem(left.type, &MF_MT_USER_DATA, &left.value, &result);
615 else
616 result = FAILED(left.hr) && FAILED(right.hr);
618 PropVariantClear(&left.value);
619 PropVariantClear(&right.value);
621 if (result)
622 *flags |= MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA;
624 return *flags == full_equality_flags ? S_OK : S_FALSE;
627 static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type, DWORD *flags)
629 struct media_type *media_type = impl_from_IMFMediaType(iface);
631 TRACE("%p, %p, %p.\n", iface, type, flags);
633 return media_type_is_equal(media_type, type, flags);
636 static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation)
638 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
640 if (IsEqualGUID(&guid, &AM_MEDIA_TYPE_REPRESENTATION))
641 return MFCreateAMMediaTypeFromMFMediaType(iface, GUID_NULL, (AM_MEDIA_TYPE **)representation);
643 if (IsEqualGUID(&guid, &FORMAT_WaveFormatEx)
644 || IsEqualGUID(&guid, &FORMAT_VideoInfo)
645 || IsEqualGUID(&guid, &FORMAT_VideoInfo2)
646 || IsEqualGUID(&guid, &FORMAT_MFVideoFormat))
647 return MFCreateAMMediaTypeFromMFMediaType(iface, guid, (AM_MEDIA_TYPE **)representation);
649 FIXME("Format %s not implemented!\n", debugstr_guid(&guid));
650 return MF_E_UNSUPPORTED_REPRESENTATION;
653 static HRESULT WINAPI mediatype_FreeRepresentation(IMFMediaType *iface, GUID guid, void *representation)
655 AM_MEDIA_TYPE *am_type = representation;
657 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
659 CoTaskMemFree(am_type->pbFormat);
660 CoTaskMemFree(am_type);
661 return S_OK;
664 static const IMFMediaTypeVtbl mediatypevtbl =
666 mediatype_QueryInterface,
667 mediatype_AddRef,
668 mediatype_Release,
669 mediatype_GetItem,
670 mediatype_GetItemType,
671 mediatype_CompareItem,
672 mediatype_Compare,
673 mediatype_GetUINT32,
674 mediatype_GetUINT64,
675 mediatype_GetDouble,
676 mediatype_GetGUID,
677 mediatype_GetStringLength,
678 mediatype_GetString,
679 mediatype_GetAllocatedString,
680 mediatype_GetBlobSize,
681 mediatype_GetBlob,
682 mediatype_GetAllocatedBlob,
683 mediatype_GetUnknown,
684 mediatype_SetItem,
685 mediatype_DeleteItem,
686 mediatype_DeleteAllItems,
687 mediatype_SetUINT32,
688 mediatype_SetUINT64,
689 mediatype_SetDouble,
690 mediatype_SetGUID,
691 mediatype_SetString,
692 mediatype_SetBlob,
693 mediatype_SetUnknown,
694 mediatype_LockStore,
695 mediatype_UnlockStore,
696 mediatype_GetCount,
697 mediatype_GetItemByIndex,
698 mediatype_CopyAllItems,
699 mediatype_GetMajorType,
700 mediatype_IsCompressedFormat,
701 mediatype_IsEqual,
702 mediatype_GetRepresentation,
703 mediatype_FreeRepresentation
706 static HRESULT WINAPI video_mediatype_QueryInterface(IMFVideoMediaType *iface, REFIID riid, void **out)
708 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
709 return IMFMediaType_QueryInterface(&media_type->IMFMediaType_iface, riid, out);
712 static ULONG WINAPI video_mediatype_AddRef(IMFVideoMediaType *iface)
714 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
715 return IMFMediaType_AddRef(&media_type->IMFMediaType_iface);
718 static ULONG WINAPI video_mediatype_Release(IMFVideoMediaType *iface)
720 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
721 return IMFMediaType_Release(&media_type->IMFMediaType_iface);
724 static HRESULT WINAPI video_mediatype_GetItem(IMFVideoMediaType *iface, REFGUID key, PROPVARIANT *value)
726 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
728 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
730 return attributes_GetItem(&media_type->attributes, key, value);
733 static HRESULT WINAPI video_mediatype_GetItemType(IMFVideoMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
735 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
737 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
739 return attributes_GetItemType(&media_type->attributes, key, type);
742 static HRESULT WINAPI video_mediatype_CompareItem(IMFVideoMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
744 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
746 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
748 return attributes_CompareItem(&media_type->attributes, key, value, result);
751 static HRESULT WINAPI video_mediatype_Compare(IMFVideoMediaType *iface, IMFAttributes *attrs,
752 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
754 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
756 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
758 return attributes_Compare(&media_type->attributes, attrs, type, result);
761 static HRESULT WINAPI video_mediatype_GetUINT32(IMFVideoMediaType *iface, REFGUID key, UINT32 *value)
763 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
765 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
767 return attributes_GetUINT32(&media_type->attributes, key, value);
770 static HRESULT WINAPI video_mediatype_GetUINT64(IMFVideoMediaType *iface, REFGUID key, UINT64 *value)
772 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
774 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
776 return attributes_GetUINT64(&media_type->attributes, key, value);
779 static HRESULT WINAPI video_mediatype_GetDouble(IMFVideoMediaType *iface, REFGUID key, double *value)
781 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
783 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
785 return attributes_GetDouble(&media_type->attributes, key, value);
788 static HRESULT WINAPI video_mediatype_GetGUID(IMFVideoMediaType *iface, REFGUID key, GUID *value)
790 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
792 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
794 return attributes_GetGUID(&media_type->attributes, key, value);
797 static HRESULT WINAPI video_mediatype_GetStringLength(IMFVideoMediaType *iface, REFGUID key, UINT32 *length)
799 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
801 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
803 return attributes_GetStringLength(&media_type->attributes, key, length);
806 static HRESULT WINAPI video_mediatype_GetString(IMFVideoMediaType *iface, REFGUID key, WCHAR *value,
807 UINT32 size, UINT32 *length)
809 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
811 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
813 return attributes_GetString(&media_type->attributes, key, value, size, length);
816 static HRESULT WINAPI video_mediatype_GetAllocatedString(IMFVideoMediaType *iface, REFGUID key,
817 WCHAR **value, UINT32 *length)
819 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
821 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
823 return attributes_GetAllocatedString(&media_type->attributes, key, value, length);
826 static HRESULT WINAPI video_mediatype_GetBlobSize(IMFVideoMediaType *iface, REFGUID key, UINT32 *size)
828 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
830 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
832 return attributes_GetBlobSize(&media_type->attributes, key, size);
835 static HRESULT WINAPI video_mediatype_GetBlob(IMFVideoMediaType *iface, REFGUID key, UINT8 *buf,
836 UINT32 bufsize, UINT32 *blobsize)
838 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
840 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
842 return attributes_GetBlob(&media_type->attributes, key, buf, bufsize, blobsize);
845 static HRESULT WINAPI video_mediatype_GetAllocatedBlob(IMFVideoMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size)
847 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
849 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
851 return attributes_GetAllocatedBlob(&media_type->attributes, key, buf, size);
854 static HRESULT WINAPI video_mediatype_GetUnknown(IMFVideoMediaType *iface, REFGUID key, REFIID riid, void **obj)
856 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
858 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), obj);
860 return attributes_GetUnknown(&media_type->attributes, key, riid, obj);
863 static HRESULT WINAPI video_mediatype_SetItem(IMFVideoMediaType *iface, REFGUID key, REFPROPVARIANT value)
865 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
867 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
869 return attributes_SetItem(&media_type->attributes, key, value);
872 static HRESULT WINAPI video_mediatype_DeleteItem(IMFVideoMediaType *iface, REFGUID key)
874 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
876 TRACE("%p, %s.\n", iface, debugstr_attr(key));
878 return attributes_DeleteItem(&media_type->attributes, key);
881 static HRESULT WINAPI video_mediatype_DeleteAllItems(IMFVideoMediaType *iface)
883 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
885 TRACE("%p.\n", iface);
887 return attributes_DeleteAllItems(&media_type->attributes);
890 static HRESULT WINAPI video_mediatype_SetUINT32(IMFVideoMediaType *iface, REFGUID key, UINT32 value)
892 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
894 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
896 return attributes_SetUINT32(&media_type->attributes, key, value);
899 static HRESULT WINAPI video_mediatype_SetUINT64(IMFVideoMediaType *iface, REFGUID key, UINT64 value)
901 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
903 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
905 return attributes_SetUINT64(&media_type->attributes, key, value);
908 static HRESULT WINAPI video_mediatype_SetDouble(IMFVideoMediaType *iface, REFGUID key, double value)
910 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
912 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
914 return attributes_SetDouble(&media_type->attributes, key, value);
917 static HRESULT WINAPI video_mediatype_SetGUID(IMFVideoMediaType *iface, REFGUID key, REFGUID value)
919 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
921 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
923 return attributes_SetGUID(&media_type->attributes, key, value);
926 static HRESULT WINAPI video_mediatype_SetString(IMFVideoMediaType *iface, REFGUID key, const WCHAR *value)
928 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
930 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
932 return attributes_SetString(&media_type->attributes, key, value);
935 static HRESULT WINAPI video_mediatype_SetBlob(IMFVideoMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size)
937 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
939 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
941 return attributes_SetBlob(&media_type->attributes, key, buf, size);
944 static HRESULT WINAPI video_mediatype_SetUnknown(IMFVideoMediaType *iface, REFGUID key, IUnknown *unknown)
946 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
948 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
950 return attributes_SetUnknown(&media_type->attributes, key, unknown);
953 static HRESULT WINAPI video_mediatype_LockStore(IMFVideoMediaType *iface)
955 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
957 TRACE("%p.\n", iface);
959 return attributes_LockStore(&media_type->attributes);
962 static HRESULT WINAPI video_mediatype_UnlockStore(IMFVideoMediaType *iface)
964 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
966 TRACE("%p.\n", iface);
968 return attributes_UnlockStore(&media_type->attributes);
971 static HRESULT WINAPI video_mediatype_GetCount(IMFVideoMediaType *iface, UINT32 *count)
973 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
975 TRACE("%p, %p.\n", iface, count);
977 return attributes_GetCount(&media_type->attributes, count);
980 static HRESULT WINAPI video_mediatype_GetItemByIndex(IMFVideoMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value)
982 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
984 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
986 return attributes_GetItemByIndex(&media_type->attributes, index, key, value);
989 static HRESULT WINAPI video_mediatype_CopyAllItems(IMFVideoMediaType *iface, IMFAttributes *dest)
991 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
993 TRACE("%p, %p.\n", iface, dest);
995 return attributes_CopyAllItems(&media_type->attributes, dest);
998 static HRESULT WINAPI video_mediatype_GetMajorType(IMFVideoMediaType *iface, GUID *guid)
1000 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
1002 TRACE("%p, %p.\n", iface, guid);
1004 return attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, guid);
1007 static HRESULT WINAPI video_mediatype_IsCompressedFormat(IMFVideoMediaType *iface, BOOL *compressed)
1009 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
1011 TRACE("%p, %p.\n", iface, compressed);
1013 return mediatype_is_compressed(media_type, compressed);
1016 static HRESULT WINAPI video_mediatype_IsEqual(IMFVideoMediaType *iface, IMFMediaType *type, DWORD *flags)
1018 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
1020 TRACE("%p, %p, %p.\n", iface, type, flags);
1022 return media_type_is_equal(media_type, type, flags);
1025 static HRESULT WINAPI video_mediatype_GetRepresentation(IMFVideoMediaType *iface, GUID guid, void **representation)
1027 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
1029 if (IsEqualGUID(&guid, &FORMAT_WaveFormatEx))
1030 return MF_E_UNSUPPORTED_REPRESENTATION;
1032 return mediatype_GetRepresentation((IMFMediaType *)iface, guid, representation);
1035 static HRESULT WINAPI video_mediatype_FreeRepresentation(IMFVideoMediaType *iface, GUID guid, void *representation)
1037 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
1038 return mediatype_FreeRepresentation((IMFMediaType *)iface, guid, representation);
1041 static const MFVIDEOFORMAT * WINAPI video_mediatype_GetVideoFormat(IMFVideoMediaType *iface)
1043 struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
1044 unsigned int size;
1045 HRESULT hr;
1047 TRACE("%p.\n", iface);
1049 CoTaskMemFree(media_type->video_format);
1050 media_type->video_format = NULL;
1051 if (FAILED(hr = MFCreateMFVideoFormatFromMFMediaType(&media_type->IMFMediaType_iface, &media_type->video_format, &size)))
1052 WARN("Failed to create format description, hr %#lx.\n", hr);
1054 return media_type->video_format;
1057 static HRESULT WINAPI video_mediatype_GetVideoRepresentation(IMFVideoMediaType *iface, GUID representation,
1058 void **data, LONG stride)
1060 FIXME("%p, %s, %p, %ld.\n", iface, debugstr_guid(&representation), data, stride);
1062 return E_NOTIMPL;
1065 static const IMFVideoMediaTypeVtbl videomediatypevtbl =
1067 video_mediatype_QueryInterface,
1068 video_mediatype_AddRef,
1069 video_mediatype_Release,
1070 video_mediatype_GetItem,
1071 video_mediatype_GetItemType,
1072 video_mediatype_CompareItem,
1073 video_mediatype_Compare,
1074 video_mediatype_GetUINT32,
1075 video_mediatype_GetUINT64,
1076 video_mediatype_GetDouble,
1077 video_mediatype_GetGUID,
1078 video_mediatype_GetStringLength,
1079 video_mediatype_GetString,
1080 video_mediatype_GetAllocatedString,
1081 video_mediatype_GetBlobSize,
1082 video_mediatype_GetBlob,
1083 video_mediatype_GetAllocatedBlob,
1084 video_mediatype_GetUnknown,
1085 video_mediatype_SetItem,
1086 video_mediatype_DeleteItem,
1087 video_mediatype_DeleteAllItems,
1088 video_mediatype_SetUINT32,
1089 video_mediatype_SetUINT64,
1090 video_mediatype_SetDouble,
1091 video_mediatype_SetGUID,
1092 video_mediatype_SetString,
1093 video_mediatype_SetBlob,
1094 video_mediatype_SetUnknown,
1095 video_mediatype_LockStore,
1096 video_mediatype_UnlockStore,
1097 video_mediatype_GetCount,
1098 video_mediatype_GetItemByIndex,
1099 video_mediatype_CopyAllItems,
1100 video_mediatype_GetMajorType,
1101 video_mediatype_IsCompressedFormat,
1102 video_mediatype_IsEqual,
1103 video_mediatype_GetRepresentation,
1104 video_mediatype_FreeRepresentation,
1105 video_mediatype_GetVideoFormat,
1106 video_mediatype_GetVideoRepresentation,
1109 static HRESULT WINAPI audio_mediatype_QueryInterface(IMFAudioMediaType *iface, REFIID riid, void **out)
1111 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1112 return IMFMediaType_QueryInterface(&media_type->IMFMediaType_iface, riid, out);
1115 static ULONG WINAPI audio_mediatype_AddRef(IMFAudioMediaType *iface)
1117 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1118 return IMFMediaType_AddRef(&media_type->IMFMediaType_iface);
1121 static ULONG WINAPI audio_mediatype_Release(IMFAudioMediaType *iface)
1123 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1124 return IMFMediaType_Release(&media_type->IMFMediaType_iface);
1127 static HRESULT WINAPI audio_mediatype_GetItem(IMFAudioMediaType *iface, REFGUID key, PROPVARIANT *value)
1129 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1131 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1133 return attributes_GetItem(&media_type->attributes, key, value);
1136 static HRESULT WINAPI audio_mediatype_GetItemType(IMFAudioMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
1138 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1140 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
1142 return attributes_GetItemType(&media_type->attributes, key, type);
1145 static HRESULT WINAPI audio_mediatype_CompareItem(IMFAudioMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
1147 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1149 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
1151 return attributes_CompareItem(&media_type->attributes, key, value, result);
1154 static HRESULT WINAPI audio_mediatype_Compare(IMFAudioMediaType *iface, IMFAttributes *attrs,
1155 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
1157 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1159 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
1161 return attributes_Compare(&media_type->attributes, attrs, type, result);
1164 static HRESULT WINAPI audio_mediatype_GetUINT32(IMFAudioMediaType *iface, REFGUID key, UINT32 *value)
1166 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1168 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1170 return attributes_GetUINT32(&media_type->attributes, key, value);
1173 static HRESULT WINAPI audio_mediatype_GetUINT64(IMFAudioMediaType *iface, REFGUID key, UINT64 *value)
1175 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1177 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1179 return attributes_GetUINT64(&media_type->attributes, key, value);
1182 static HRESULT WINAPI audio_mediatype_GetDouble(IMFAudioMediaType *iface, REFGUID key, double *value)
1184 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1186 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1188 return attributes_GetDouble(&media_type->attributes, key, value);
1191 static HRESULT WINAPI audio_mediatype_GetGUID(IMFAudioMediaType *iface, REFGUID key, GUID *value)
1193 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1195 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1197 return attributes_GetGUID(&media_type->attributes, key, value);
1200 static HRESULT WINAPI audio_mediatype_GetStringLength(IMFAudioMediaType *iface, REFGUID key, UINT32 *length)
1202 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1204 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
1206 return attributes_GetStringLength(&media_type->attributes, key, length);
1209 static HRESULT WINAPI audio_mediatype_GetString(IMFAudioMediaType *iface, REFGUID key, WCHAR *value,
1210 UINT32 size, UINT32 *length)
1212 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1214 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
1216 return attributes_GetString(&media_type->attributes, key, value, size, length);
1219 static HRESULT WINAPI audio_mediatype_GetAllocatedString(IMFAudioMediaType *iface, REFGUID key,
1220 WCHAR **value, UINT32 *length)
1222 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1224 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
1226 return attributes_GetAllocatedString(&media_type->attributes, key, value, length);
1229 static HRESULT WINAPI audio_mediatype_GetBlobSize(IMFAudioMediaType *iface, REFGUID key, UINT32 *size)
1231 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1233 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
1235 return attributes_GetBlobSize(&media_type->attributes, key, size);
1238 static HRESULT WINAPI audio_mediatype_GetBlob(IMFAudioMediaType *iface, REFGUID key, UINT8 *buf,
1239 UINT32 bufsize, UINT32 *blobsize)
1241 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1243 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
1245 return attributes_GetBlob(&media_type->attributes, key, buf, bufsize, blobsize);
1248 static HRESULT WINAPI audio_mediatype_GetAllocatedBlob(IMFAudioMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size)
1250 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1252 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
1254 return attributes_GetAllocatedBlob(&media_type->attributes, key, buf, size);
1257 static HRESULT WINAPI audio_mediatype_GetUnknown(IMFAudioMediaType *iface, REFGUID key, REFIID riid, void **obj)
1259 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1261 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), obj);
1263 return attributes_GetUnknown(&media_type->attributes, key, riid, obj);
1266 static HRESULT WINAPI audio_mediatype_SetItem(IMFAudioMediaType *iface, REFGUID key, REFPROPVARIANT value)
1268 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1270 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
1272 return attributes_SetItem(&media_type->attributes, key, value);
1275 static HRESULT WINAPI audio_mediatype_DeleteItem(IMFAudioMediaType *iface, REFGUID key)
1277 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1279 TRACE("%p, %s.\n", iface, debugstr_attr(key));
1281 return attributes_DeleteItem(&media_type->attributes, key);
1284 static HRESULT WINAPI audio_mediatype_DeleteAllItems(IMFAudioMediaType *iface)
1286 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1288 TRACE("%p.\n", iface);
1290 return attributes_DeleteAllItems(&media_type->attributes);
1293 static HRESULT WINAPI audio_mediatype_SetUINT32(IMFAudioMediaType *iface, REFGUID key, UINT32 value)
1295 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1297 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
1299 return attributes_SetUINT32(&media_type->attributes, key, value);
1302 static HRESULT WINAPI audio_mediatype_SetUINT64(IMFAudioMediaType *iface, REFGUID key, UINT64 value)
1304 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1306 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
1308 return attributes_SetUINT64(&media_type->attributes, key, value);
1311 static HRESULT WINAPI audio_mediatype_SetDouble(IMFAudioMediaType *iface, REFGUID key, double value)
1313 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1315 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
1317 return attributes_SetDouble(&media_type->attributes, key, value);
1320 static HRESULT WINAPI audio_mediatype_SetGUID(IMFAudioMediaType *iface, REFGUID key, REFGUID value)
1322 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1324 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
1326 return attributes_SetGUID(&media_type->attributes, key, value);
1329 static HRESULT WINAPI audio_mediatype_SetString(IMFAudioMediaType *iface, REFGUID key, const WCHAR *value)
1331 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1333 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
1335 return attributes_SetString(&media_type->attributes, key, value);
1338 static HRESULT WINAPI audio_mediatype_SetBlob(IMFAudioMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size)
1340 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1342 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
1344 return attributes_SetBlob(&media_type->attributes, key, buf, size);
1347 static HRESULT WINAPI audio_mediatype_SetUnknown(IMFAudioMediaType *iface, REFGUID key, IUnknown *unknown)
1349 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1351 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
1353 return attributes_SetUnknown(&media_type->attributes, key, unknown);
1356 static HRESULT WINAPI audio_mediatype_LockStore(IMFAudioMediaType *iface)
1358 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1360 TRACE("%p.\n", iface);
1362 return attributes_LockStore(&media_type->attributes);
1365 static HRESULT WINAPI audio_mediatype_UnlockStore(IMFAudioMediaType *iface)
1367 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1369 TRACE("%p.\n", iface);
1371 return attributes_UnlockStore(&media_type->attributes);
1374 static HRESULT WINAPI audio_mediatype_GetCount(IMFAudioMediaType *iface, UINT32 *count)
1376 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1378 TRACE("%p, %p.\n", iface, count);
1380 return attributes_GetCount(&media_type->attributes, count);
1383 static HRESULT WINAPI audio_mediatype_GetItemByIndex(IMFAudioMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value)
1385 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1387 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
1389 return attributes_GetItemByIndex(&media_type->attributes, index, key, value);
1392 static HRESULT WINAPI audio_mediatype_CopyAllItems(IMFAudioMediaType *iface, IMFAttributes *dest)
1394 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1396 TRACE("%p, %p.\n", iface, dest);
1398 return attributes_CopyAllItems(&media_type->attributes, dest);
1401 static HRESULT WINAPI audio_mediatype_GetMajorType(IMFAudioMediaType *iface, GUID *guid)
1403 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1405 TRACE("%p, %p.\n", iface, guid);
1407 return attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, guid);
1410 static HRESULT WINAPI audio_mediatype_IsCompressedFormat(IMFAudioMediaType *iface, BOOL *compressed)
1412 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1414 TRACE("%p, %p.\n", iface, compressed);
1416 return mediatype_is_compressed(media_type, compressed);
1419 static HRESULT WINAPI audio_mediatype_IsEqual(IMFAudioMediaType *iface, IMFMediaType *type, DWORD *flags)
1421 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1423 TRACE("%p, %p, %p.\n", iface, type, flags);
1425 return media_type_is_equal(media_type, type, flags);
1428 static HRESULT WINAPI audio_mediatype_GetRepresentation(IMFAudioMediaType *iface, GUID guid, void **representation)
1430 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
1432 if (IsEqualGUID(&guid, &FORMAT_VideoInfo)
1433 || IsEqualGUID(&guid, &FORMAT_VideoInfo2)
1434 || IsEqualGUID(&guid, &FORMAT_MFVideoFormat))
1435 return E_INVALIDARG;
1437 return mediatype_GetRepresentation((IMFMediaType *)iface, guid, representation);
1440 static HRESULT WINAPI audio_mediatype_FreeRepresentation(IMFAudioMediaType *iface, GUID guid, void *representation)
1442 TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
1443 return mediatype_FreeRepresentation((IMFMediaType *)iface, guid, representation);
1446 static const WAVEFORMATEX * WINAPI audio_mediatype_GetAudioFormat(IMFAudioMediaType *iface)
1448 struct media_type *media_type = impl_from_IMFAudioMediaType(iface);
1449 unsigned int size;
1450 HRESULT hr;
1452 TRACE("%p.\n", iface);
1454 CoTaskMemFree(media_type->audio_format);
1455 media_type->audio_format = NULL;
1456 if (FAILED(hr = MFCreateWaveFormatExFromMFMediaType(&media_type->IMFMediaType_iface, &media_type->audio_format,
1457 &size, MFWaveFormatExConvertFlag_Normal)))
1459 WARN("Failed to create wave format description, hr %#lx.\n", hr);
1462 return media_type->audio_format;
1465 static const IMFAudioMediaTypeVtbl audiomediatypevtbl =
1467 audio_mediatype_QueryInterface,
1468 audio_mediatype_AddRef,
1469 audio_mediatype_Release,
1470 audio_mediatype_GetItem,
1471 audio_mediatype_GetItemType,
1472 audio_mediatype_CompareItem,
1473 audio_mediatype_Compare,
1474 audio_mediatype_GetUINT32,
1475 audio_mediatype_GetUINT64,
1476 audio_mediatype_GetDouble,
1477 audio_mediatype_GetGUID,
1478 audio_mediatype_GetStringLength,
1479 audio_mediatype_GetString,
1480 audio_mediatype_GetAllocatedString,
1481 audio_mediatype_GetBlobSize,
1482 audio_mediatype_GetBlob,
1483 audio_mediatype_GetAllocatedBlob,
1484 audio_mediatype_GetUnknown,
1485 audio_mediatype_SetItem,
1486 audio_mediatype_DeleteItem,
1487 audio_mediatype_DeleteAllItems,
1488 audio_mediatype_SetUINT32,
1489 audio_mediatype_SetUINT64,
1490 audio_mediatype_SetDouble,
1491 audio_mediatype_SetGUID,
1492 audio_mediatype_SetString,
1493 audio_mediatype_SetBlob,
1494 audio_mediatype_SetUnknown,
1495 audio_mediatype_LockStore,
1496 audio_mediatype_UnlockStore,
1497 audio_mediatype_GetCount,
1498 audio_mediatype_GetItemByIndex,
1499 audio_mediatype_CopyAllItems,
1500 audio_mediatype_GetMajorType,
1501 audio_mediatype_IsCompressedFormat,
1502 audio_mediatype_IsEqual,
1503 audio_mediatype_GetRepresentation,
1504 audio_mediatype_FreeRepresentation,
1505 audio_mediatype_GetAudioFormat,
1508 static HRESULT create_media_type(struct media_type **ret)
1510 struct media_type *object;
1511 HRESULT hr;
1513 if (!(object = calloc(1, sizeof(*object))))
1514 return E_OUTOFMEMORY;
1516 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
1518 free(object);
1519 return hr;
1521 object->IMFMediaType_iface.lpVtbl = &mediatypevtbl;
1522 object->IMFVideoMediaType_iface.lpVtbl = &videomediatypevtbl;
1523 object->IMFAudioMediaType_iface.lpVtbl = &audiomediatypevtbl;
1525 *ret = object;
1527 return S_OK;
1530 /***********************************************************************
1531 * MFCreateMediaType (mfplat.@)
1533 HRESULT WINAPI MFCreateMediaType(IMFMediaType **media_type)
1535 struct media_type *object;
1536 HRESULT hr;
1538 TRACE("%p.\n", media_type);
1540 if (!media_type)
1541 return E_INVALIDARG;
1543 if (FAILED(hr = create_media_type(&object)))
1544 return hr;
1546 *media_type = &object->IMFMediaType_iface;
1548 TRACE("Created media type %p.\n", *media_type);
1550 return S_OK;
1553 static HRESULT WINAPI stream_descriptor_QueryInterface(IMFStreamDescriptor *iface, REFIID riid, void **out)
1555 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
1557 if (IsEqualIID(riid, &IID_IMFStreamDescriptor) ||
1558 IsEqualIID(riid, &IID_IMFAttributes) ||
1559 IsEqualIID(riid, &IID_IUnknown))
1561 *out = iface;
1562 IMFStreamDescriptor_AddRef(iface);
1563 return S_OK;
1566 WARN("Unsupported %s.\n", debugstr_guid(riid));
1567 *out = NULL;
1568 return E_NOINTERFACE;
1571 static ULONG WINAPI stream_descriptor_AddRef(IMFStreamDescriptor *iface)
1573 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1574 ULONG refcount = InterlockedIncrement(&stream_desc->attributes.ref);
1576 TRACE("%p, refcount %lu.\n", iface, refcount);
1578 return refcount;
1581 static ULONG WINAPI stream_descriptor_Release(IMFStreamDescriptor *iface)
1583 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1584 ULONG refcount = InterlockedDecrement(&stream_desc->attributes.ref);
1585 unsigned int i;
1587 TRACE("%p, refcount %lu.\n", iface, refcount);
1589 if (!refcount)
1591 for (i = 0; i < stream_desc->media_types_count; ++i)
1593 if (stream_desc->media_types[i])
1594 IMFMediaType_Release(stream_desc->media_types[i]);
1596 free(stream_desc->media_types);
1597 if (stream_desc->current_type)
1598 IMFMediaType_Release(stream_desc->current_type);
1599 clear_attributes_object(&stream_desc->attributes);
1600 free(stream_desc);
1603 return refcount;
1606 static HRESULT WINAPI stream_descriptor_GetItem(IMFStreamDescriptor *iface, REFGUID key, PROPVARIANT *value)
1608 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1610 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1612 return attributes_GetItem(&stream_desc->attributes, key, value);
1615 static HRESULT WINAPI stream_descriptor_GetItemType(IMFStreamDescriptor *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
1617 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1619 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
1621 return attributes_GetItemType(&stream_desc->attributes, key, type);
1624 static HRESULT WINAPI stream_descriptor_CompareItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value,
1625 BOOL *result)
1627 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1629 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
1631 return attributes_CompareItem(&stream_desc->attributes, key, value, result);
1634 static HRESULT WINAPI stream_descriptor_Compare(IMFStreamDescriptor *iface, IMFAttributes *theirs,
1635 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
1637 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1639 TRACE("%p, %p, %d, %p.\n", iface, theirs, type, result);
1641 return attributes_Compare(&stream_desc->attributes, theirs, type, result);
1644 static HRESULT WINAPI stream_descriptor_GetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 *value)
1646 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1648 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1650 return attributes_GetUINT32(&stream_desc->attributes, key, value);
1653 static HRESULT WINAPI stream_descriptor_GetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 *value)
1655 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1657 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1659 return attributes_GetUINT64(&stream_desc->attributes, key, value);
1662 static HRESULT WINAPI stream_descriptor_GetDouble(IMFStreamDescriptor *iface, REFGUID key, double *value)
1664 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1666 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1668 return attributes_GetDouble(&stream_desc->attributes, key, value);
1671 static HRESULT WINAPI stream_descriptor_GetGUID(IMFStreamDescriptor *iface, REFGUID key, GUID *value)
1673 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1675 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
1677 return attributes_GetGUID(&stream_desc->attributes, key, value);
1680 static HRESULT WINAPI stream_descriptor_GetStringLength(IMFStreamDescriptor *iface, REFGUID key, UINT32 *length)
1682 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1684 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
1686 return attributes_GetStringLength(&stream_desc->attributes, key, length);
1689 static HRESULT WINAPI stream_descriptor_GetString(IMFStreamDescriptor *iface, REFGUID key, WCHAR *value,
1690 UINT32 size, UINT32 *length)
1692 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1694 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
1696 return attributes_GetString(&stream_desc->attributes, key, value, size, length);
1699 static HRESULT WINAPI stream_descriptor_GetAllocatedString(IMFStreamDescriptor *iface, REFGUID key,
1700 WCHAR **value, UINT32 *length)
1702 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1704 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
1706 return attributes_GetAllocatedString(&stream_desc->attributes, key, value, length);
1709 static HRESULT WINAPI stream_descriptor_GetBlobSize(IMFStreamDescriptor *iface, REFGUID key, UINT32 *size)
1711 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1713 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
1715 return attributes_GetBlobSize(&stream_desc->attributes, key, size);
1718 static HRESULT WINAPI stream_descriptor_GetBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 *buf,
1719 UINT32 bufsize, UINT32 *blobsize)
1721 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1723 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
1725 return attributes_GetBlob(&stream_desc->attributes, key, buf, bufsize, blobsize);
1728 static HRESULT WINAPI stream_descriptor_GetAllocatedBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 **buf,
1729 UINT32 *size)
1731 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1733 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
1735 return attributes_GetAllocatedBlob(&stream_desc->attributes, key, buf, size);
1738 static HRESULT WINAPI stream_descriptor_GetUnknown(IMFStreamDescriptor *iface, REFGUID key, REFIID riid, void **out)
1740 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1742 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), out);
1744 return attributes_GetUnknown(&stream_desc->attributes, key, riid, out);
1747 static HRESULT WINAPI stream_descriptor_SetItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value)
1749 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1751 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
1753 return attributes_SetItem(&stream_desc->attributes, key, value);
1756 static HRESULT WINAPI stream_descriptor_DeleteItem(IMFStreamDescriptor *iface, REFGUID key)
1758 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1760 TRACE("%p, %s.\n", iface, debugstr_attr(key));
1762 return attributes_DeleteItem(&stream_desc->attributes, key);
1765 static HRESULT WINAPI stream_descriptor_DeleteAllItems(IMFStreamDescriptor *iface)
1767 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1769 TRACE("%p.\n", iface);
1771 return attributes_DeleteAllItems(&stream_desc->attributes);
1774 static HRESULT WINAPI stream_descriptor_SetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 value)
1776 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1778 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
1780 return attributes_SetUINT32(&stream_desc->attributes, key, value);
1783 static HRESULT WINAPI stream_descriptor_SetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 value)
1785 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1787 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
1789 return attributes_SetUINT64(&stream_desc->attributes, key, value);
1792 static HRESULT WINAPI stream_descriptor_SetDouble(IMFStreamDescriptor *iface, REFGUID key, double value)
1794 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1796 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
1798 return attributes_SetDouble(&stream_desc->attributes, key, value);
1801 static HRESULT WINAPI stream_descriptor_SetGUID(IMFStreamDescriptor *iface, REFGUID key, REFGUID value)
1803 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1805 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
1807 return attributes_SetGUID(&stream_desc->attributes, key, value);
1810 static HRESULT WINAPI stream_descriptor_SetString(IMFStreamDescriptor *iface, REFGUID key, const WCHAR *value)
1812 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1814 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
1816 return attributes_SetString(&stream_desc->attributes, key, value);
1819 static HRESULT WINAPI stream_descriptor_SetBlob(IMFStreamDescriptor *iface, REFGUID key, const UINT8 *buf, UINT32 size)
1821 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1823 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
1825 return attributes_SetBlob(&stream_desc->attributes, key, buf, size);
1828 static HRESULT WINAPI stream_descriptor_SetUnknown(IMFStreamDescriptor *iface, REFGUID key, IUnknown *unknown)
1830 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1832 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
1834 return attributes_SetUnknown(&stream_desc->attributes, key, unknown);
1837 static HRESULT WINAPI stream_descriptor_LockStore(IMFStreamDescriptor *iface)
1839 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1841 TRACE("%p.\n", iface);
1843 return attributes_LockStore(&stream_desc->attributes);
1846 static HRESULT WINAPI stream_descriptor_UnlockStore(IMFStreamDescriptor *iface)
1848 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1850 TRACE("%p.\n", iface);
1852 return attributes_UnlockStore(&stream_desc->attributes);
1855 static HRESULT WINAPI stream_descriptor_GetCount(IMFStreamDescriptor *iface, UINT32 *count)
1857 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1859 TRACE("%p, %p.\n", iface, count);
1861 return attributes_GetCount(&stream_desc->attributes, count);
1864 static HRESULT WINAPI stream_descriptor_GetItemByIndex(IMFStreamDescriptor *iface, UINT32 index, GUID *key,
1865 PROPVARIANT *value)
1867 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1869 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
1871 return attributes_GetItemByIndex(&stream_desc->attributes, index, key, value);
1874 static HRESULT WINAPI stream_descriptor_CopyAllItems(IMFStreamDescriptor *iface, IMFAttributes *dest)
1876 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1878 TRACE("%p, %p.\n", iface, dest);
1880 return attributes_CopyAllItems(&stream_desc->attributes, dest);
1883 static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier)
1885 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1887 TRACE("%p, %p.\n", iface, identifier);
1889 *identifier = stream_desc->identifier;
1891 return S_OK;
1894 static HRESULT WINAPI stream_descriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler)
1896 struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
1898 TRACE("%p, %p.\n", iface, handler);
1900 *handler = &stream_desc->IMFMediaTypeHandler_iface;
1901 IMFMediaTypeHandler_AddRef(*handler);
1903 return S_OK;
1906 static const IMFStreamDescriptorVtbl streamdescriptorvtbl =
1908 stream_descriptor_QueryInterface,
1909 stream_descriptor_AddRef,
1910 stream_descriptor_Release,
1911 stream_descriptor_GetItem,
1912 stream_descriptor_GetItemType,
1913 stream_descriptor_CompareItem,
1914 stream_descriptor_Compare,
1915 stream_descriptor_GetUINT32,
1916 stream_descriptor_GetUINT64,
1917 stream_descriptor_GetDouble,
1918 stream_descriptor_GetGUID,
1919 stream_descriptor_GetStringLength,
1920 stream_descriptor_GetString,
1921 stream_descriptor_GetAllocatedString,
1922 stream_descriptor_GetBlobSize,
1923 stream_descriptor_GetBlob,
1924 stream_descriptor_GetAllocatedBlob,
1925 stream_descriptor_GetUnknown,
1926 stream_descriptor_SetItem,
1927 stream_descriptor_DeleteItem,
1928 stream_descriptor_DeleteAllItems,
1929 stream_descriptor_SetUINT32,
1930 stream_descriptor_SetUINT64,
1931 stream_descriptor_SetDouble,
1932 stream_descriptor_SetGUID,
1933 stream_descriptor_SetString,
1934 stream_descriptor_SetBlob,
1935 stream_descriptor_SetUnknown,
1936 stream_descriptor_LockStore,
1937 stream_descriptor_UnlockStore,
1938 stream_descriptor_GetCount,
1939 stream_descriptor_GetItemByIndex,
1940 stream_descriptor_CopyAllItems,
1941 stream_descriptor_GetStreamIdentifier,
1942 stream_descriptor_GetMediaTypeHandler
1945 static HRESULT WINAPI mediatype_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, void **obj)
1947 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
1949 if (IsEqualIID(riid, &IID_IMFMediaTypeHandler) ||
1950 IsEqualIID(riid, &IID_IUnknown))
1952 *obj = iface;
1953 IMFMediaTypeHandler_AddRef(iface);
1954 return S_OK;
1957 WARN("Unsupported %s.\n", debugstr_guid(riid));
1958 *obj = NULL;
1959 return E_NOINTERFACE;
1962 static ULONG WINAPI mediatype_handler_AddRef(IMFMediaTypeHandler *iface)
1964 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1965 return IMFStreamDescriptor_AddRef(&stream_desc->IMFStreamDescriptor_iface);
1968 static ULONG WINAPI mediatype_handler_Release(IMFMediaTypeHandler *iface)
1970 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1971 return IMFStreamDescriptor_Release(&stream_desc->IMFStreamDescriptor_iface);
1974 static BOOL stream_descriptor_is_mediatype_supported(IMFMediaType *media_type, IMFMediaType *candidate)
1976 DWORD flags = 0;
1978 if (FAILED(IMFMediaType_IsEqual(media_type, candidate, &flags)))
1979 return FALSE;
1981 return (flags & (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES)) ==
1982 (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES);
1985 static HRESULT WINAPI mediatype_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, IMFMediaType *in_type,
1986 IMFMediaType **out_type)
1988 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
1989 BOOL supported = FALSE;
1990 unsigned int i;
1992 TRACE("%p, %p, %p.\n", iface, in_type, out_type);
1994 if (!in_type)
1995 return E_POINTER;
1997 if (out_type)
1998 *out_type = NULL;
2000 EnterCriticalSection(&stream_desc->attributes.cs);
2002 supported = stream_desc->current_type && stream_descriptor_is_mediatype_supported(stream_desc->current_type, in_type);
2003 if (!supported)
2005 for (i = 0; i < stream_desc->media_types_count; ++i)
2007 if ((supported = stream_descriptor_is_mediatype_supported(stream_desc->media_types[i], in_type)))
2008 break;
2012 LeaveCriticalSection(&stream_desc->attributes.cs);
2014 return supported ? S_OK : MF_E_INVALIDMEDIATYPE;
2017 static HRESULT WINAPI mediatype_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count)
2019 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
2021 TRACE("%p, %p.\n", iface, count);
2023 *count = stream_desc->media_types_count;
2025 return S_OK;
2028 static HRESULT WINAPI mediatype_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index,
2029 IMFMediaType **type)
2031 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
2033 TRACE("%p, %lu, %p.\n", iface, index, type);
2035 if (index >= stream_desc->media_types_count)
2036 return MF_E_NO_MORE_TYPES;
2038 if (stream_desc->media_types[index])
2040 *type = stream_desc->media_types[index];
2041 IMFMediaType_AddRef(*type);
2044 return stream_desc->media_types[index] ? S_OK : E_FAIL;
2047 static HRESULT WINAPI mediatype_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *type)
2049 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
2051 TRACE("%p, %p.\n", iface, type);
2053 if (!type)
2054 return E_POINTER;
2056 EnterCriticalSection(&stream_desc->attributes.cs);
2057 if (stream_desc->current_type)
2058 IMFMediaType_Release(stream_desc->current_type);
2059 stream_desc->current_type = type;
2060 IMFMediaType_AddRef(stream_desc->current_type);
2061 LeaveCriticalSection(&stream_desc->attributes.cs);
2063 return S_OK;
2066 static HRESULT WINAPI mediatype_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **type)
2068 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
2069 HRESULT hr = S_OK;
2071 TRACE("%p, %p.\n", iface, type);
2073 EnterCriticalSection(&stream_desc->attributes.cs);
2074 if (stream_desc->current_type)
2076 *type = stream_desc->current_type;
2077 IMFMediaType_AddRef(*type);
2079 else
2080 hr = MF_E_NOT_INITIALIZED;
2081 LeaveCriticalSection(&stream_desc->attributes.cs);
2083 return hr;
2086 static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type)
2088 struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
2089 HRESULT hr;
2091 TRACE("%p, %p.\n", iface, type);
2093 EnterCriticalSection(&stream_desc->attributes.cs);
2094 hr = IMFMediaType_GetGUID(stream_desc->current_type ? stream_desc->current_type :
2095 stream_desc->media_types[0], &MF_MT_MAJOR_TYPE, type);
2096 LeaveCriticalSection(&stream_desc->attributes.cs);
2098 return hr;
2101 static const IMFMediaTypeHandlerVtbl mediatypehandlervtbl =
2103 mediatype_handler_QueryInterface,
2104 mediatype_handler_AddRef,
2105 mediatype_handler_Release,
2106 mediatype_handler_IsMediaTypeSupported,
2107 mediatype_handler_GetMediaTypeCount,
2108 mediatype_handler_GetMediaTypeByIndex,
2109 mediatype_handler_SetCurrentMediaType,
2110 mediatype_handler_GetCurrentMediaType,
2111 mediatype_handler_GetMajorType,
2114 /***********************************************************************
2115 * MFCreateStreamDescriptor (mfplat.@)
2117 HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
2118 IMFMediaType **types, IMFStreamDescriptor **descriptor)
2120 struct stream_desc *object;
2121 unsigned int i;
2122 HRESULT hr;
2124 TRACE("%ld, %ld, %p, %p.\n", identifier, count, types, descriptor);
2126 if (!count)
2127 return E_INVALIDARG;
2129 if (!(object = calloc(1, sizeof(*object))))
2130 return E_OUTOFMEMORY;
2132 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
2134 free(object);
2135 return hr;
2137 object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl;
2138 object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl;
2139 object->identifier = identifier;
2140 object->media_types = calloc(count, sizeof(*object->media_types));
2141 if (!object->media_types)
2143 IMFStreamDescriptor_Release(&object->IMFStreamDescriptor_iface);
2144 return E_OUTOFMEMORY;
2146 for (i = 0; i < count; ++i)
2148 object->media_types[i] = types[i];
2149 if (object->media_types[i])
2150 IMFMediaType_AddRef(object->media_types[i]);
2152 object->media_types_count = count;
2154 *descriptor = &object->IMFStreamDescriptor_iface;
2156 return S_OK;
2159 static HRESULT WINAPI presentation_descriptor_QueryInterface(IMFPresentationDescriptor *iface, REFIID riid, void **out)
2161 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
2163 if (IsEqualIID(riid, &IID_IMFPresentationDescriptor) ||
2164 IsEqualIID(riid, &IID_IMFAttributes) ||
2165 IsEqualIID(riid, &IID_IUnknown))
2167 *out = iface;
2168 IMFPresentationDescriptor_AddRef(iface);
2169 return S_OK;
2172 WARN("Unsupported %s.\n", debugstr_guid(riid));
2173 *out = NULL;
2174 return E_NOINTERFACE;
2177 static ULONG WINAPI presentation_descriptor_AddRef(IMFPresentationDescriptor *iface)
2179 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2180 ULONG refcount = InterlockedIncrement(&presentation_desc->attributes.ref);
2182 TRACE("%p, refcount %lu.\n", iface, refcount);
2184 return refcount;
2187 static ULONG WINAPI presentation_descriptor_Release(IMFPresentationDescriptor *iface)
2189 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2190 ULONG refcount = InterlockedDecrement(&presentation_desc->attributes.ref);
2191 unsigned int i;
2193 TRACE("%p, refcount %lu.\n", iface, refcount);
2195 if (!refcount)
2197 for (i = 0; i < presentation_desc->count; ++i)
2199 if (presentation_desc->descriptors[i].descriptor)
2200 IMFStreamDescriptor_Release(presentation_desc->descriptors[i].descriptor);
2202 clear_attributes_object(&presentation_desc->attributes);
2203 free(presentation_desc->descriptors);
2204 free(presentation_desc);
2207 return refcount;
2210 static HRESULT WINAPI presentation_descriptor_GetItem(IMFPresentationDescriptor *iface, REFGUID key,
2211 PROPVARIANT *value)
2213 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2215 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
2217 return attributes_GetItem(&presentation_desc->attributes, key, value);
2220 static HRESULT WINAPI presentation_descriptor_GetItemType(IMFPresentationDescriptor *iface, REFGUID key,
2221 MF_ATTRIBUTE_TYPE *type)
2223 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2225 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
2227 return attributes_GetItemType(&presentation_desc->attributes, key, type);
2230 static HRESULT WINAPI presentation_descriptor_CompareItem(IMFPresentationDescriptor *iface, REFGUID key,
2231 REFPROPVARIANT value, BOOL *result)
2233 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2235 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result);
2237 return attributes_CompareItem(&presentation_desc->attributes, key, value, result);
2240 static HRESULT WINAPI presentation_descriptor_Compare(IMFPresentationDescriptor *iface, IMFAttributes *attrs,
2241 MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result)
2243 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2245 TRACE("%p, %p, %d, %p.\n", iface, attrs, type, result);
2247 return attributes_Compare(&presentation_desc->attributes, attrs, type, result);
2250 static HRESULT WINAPI presentation_descriptor_GetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *value)
2252 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2254 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
2256 return attributes_GetUINT32(&presentation_desc->attributes, key, value);
2259 static HRESULT WINAPI presentation_descriptor_GetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 *value)
2261 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2263 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
2265 return attributes_GetUINT64(&presentation_desc->attributes, key, value);
2268 static HRESULT WINAPI presentation_descriptor_GetDouble(IMFPresentationDescriptor *iface, REFGUID key, double *value)
2270 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2272 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
2274 return attributes_GetDouble(&presentation_desc->attributes, key, value);
2277 static HRESULT WINAPI presentation_descriptor_GetGUID(IMFPresentationDescriptor *iface, REFGUID key, GUID *value)
2279 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2281 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
2283 return attributes_GetGUID(&presentation_desc->attributes, key, value);
2286 static HRESULT WINAPI presentation_descriptor_GetStringLength(IMFPresentationDescriptor *iface, REFGUID key,
2287 UINT32 *length)
2289 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2291 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length);
2293 return attributes_GetStringLength(&presentation_desc->attributes, key, length);
2296 static HRESULT WINAPI presentation_descriptor_GetString(IMFPresentationDescriptor *iface, REFGUID key, WCHAR *value,
2297 UINT32 size, UINT32 *length)
2299 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2301 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), value, size, length);
2303 return attributes_GetString(&presentation_desc->attributes, key, value, size, length);
2306 static HRESULT WINAPI presentation_descriptor_GetAllocatedString(IMFPresentationDescriptor *iface, REFGUID key,
2307 WCHAR **value, UINT32 *length)
2309 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2311 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length);
2313 return attributes_GetAllocatedString(&presentation_desc->attributes, key, value, length);
2316 static HRESULT WINAPI presentation_descriptor_GetBlobSize(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *size)
2318 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2320 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size);
2322 return attributes_GetBlobSize(&presentation_desc->attributes, key, size);
2325 static HRESULT WINAPI presentation_descriptor_GetBlob(IMFPresentationDescriptor *iface, REFGUID key, UINT8 *buf,
2326 UINT32 bufsize, UINT32 *blobsize)
2328 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2330 TRACE("%p, %s, %p, %u, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize);
2332 return attributes_GetBlob(&presentation_desc->attributes, key, buf, bufsize, blobsize);
2335 static HRESULT WINAPI presentation_descriptor_GetAllocatedBlob(IMFPresentationDescriptor *iface, REFGUID key,
2336 UINT8 **buf, UINT32 *size)
2338 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2340 TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size);
2342 return attributes_GetAllocatedBlob(&presentation_desc->attributes, key, buf, size);
2345 static HRESULT WINAPI presentation_descriptor_GetUnknown(IMFPresentationDescriptor *iface, REFGUID key,
2346 REFIID riid, void **out)
2348 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2350 TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), out);
2352 return attributes_GetUnknown(&presentation_desc->attributes, key, riid, out);
2355 static HRESULT WINAPI presentation_descriptor_SetItem(IMFPresentationDescriptor *iface, REFGUID key,
2356 REFPROPVARIANT value)
2358 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2360 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value));
2362 return attributes_SetItem(&presentation_desc->attributes, key, value);
2365 static HRESULT WINAPI presentation_descriptor_DeleteItem(IMFPresentationDescriptor *iface, REFGUID key)
2367 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2369 TRACE("%p, %s.\n", iface, debugstr_attr(key));
2371 return attributes_DeleteItem(&presentation_desc->attributes, key);
2374 static HRESULT WINAPI presentation_descriptor_DeleteAllItems(IMFPresentationDescriptor *iface)
2376 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2378 TRACE("%p.\n", iface);
2380 return attributes_DeleteAllItems(&presentation_desc->attributes);
2383 static HRESULT WINAPI presentation_descriptor_SetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 value)
2385 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2387 TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value);
2389 return attributes_SetUINT32(&presentation_desc->attributes, key, value);
2392 static HRESULT WINAPI presentation_descriptor_SetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 value)
2394 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2396 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value));
2398 return attributes_SetUINT64(&presentation_desc->attributes, key, value);
2401 static HRESULT WINAPI presentation_descriptor_SetDouble(IMFPresentationDescriptor *iface, REFGUID key, double value)
2403 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2405 TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value);
2407 return attributes_SetDouble(&presentation_desc->attributes, key, value);
2410 static HRESULT WINAPI presentation_descriptor_SetGUID(IMFPresentationDescriptor *iface, REFGUID key, REFGUID value)
2412 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2414 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value));
2416 return attributes_SetGUID(&presentation_desc->attributes, key, value);
2419 static HRESULT WINAPI presentation_descriptor_SetString(IMFPresentationDescriptor *iface, REFGUID key,
2420 const WCHAR *value)
2422 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2424 TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value));
2426 return attributes_SetString(&presentation_desc->attributes, key, value);
2429 static HRESULT WINAPI presentation_descriptor_SetBlob(IMFPresentationDescriptor *iface, REFGUID key, const UINT8 *buf,
2430 UINT32 size)
2432 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2434 TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size);
2436 return attributes_SetBlob(&presentation_desc->attributes, key, buf, size);
2439 static HRESULT WINAPI presentation_descriptor_SetUnknown(IMFPresentationDescriptor *iface, REFGUID key,
2440 IUnknown *unknown)
2442 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2444 TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown);
2446 return attributes_SetUnknown(&presentation_desc->attributes, key, unknown);
2449 static HRESULT WINAPI presentation_descriptor_LockStore(IMFPresentationDescriptor *iface)
2451 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2453 TRACE("%p.\n", iface);
2455 return attributes_LockStore(&presentation_desc->attributes);
2458 static HRESULT WINAPI presentation_descriptor_UnlockStore(IMFPresentationDescriptor *iface)
2460 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2462 TRACE("%p.\n", iface);
2464 return attributes_UnlockStore(&presentation_desc->attributes);
2467 static HRESULT WINAPI presentation_descriptor_GetCount(IMFPresentationDescriptor *iface, UINT32 *count)
2469 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2471 TRACE("%p, %p.\n", iface, count);
2473 return attributes_GetCount(&presentation_desc->attributes, count);
2476 static HRESULT WINAPI presentation_descriptor_GetItemByIndex(IMFPresentationDescriptor *iface, UINT32 index, GUID *key,
2477 PROPVARIANT *value)
2479 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2481 TRACE("%p, %u, %p, %p.\n", iface, index, key, value);
2483 return attributes_GetItemByIndex(&presentation_desc->attributes, index, key, value);
2486 static HRESULT WINAPI presentation_descriptor_CopyAllItems(IMFPresentationDescriptor *iface, IMFAttributes *dest)
2488 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2490 TRACE("%p, %p.\n", iface, dest);
2492 return attributes_CopyAllItems(&presentation_desc->attributes, dest);
2495 static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorCount(IMFPresentationDescriptor *iface, DWORD *count)
2497 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2499 TRACE("%p, %p.\n", iface, count);
2501 *count = presentation_desc->count;
2503 return S_OK;
2506 static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorByIndex(IMFPresentationDescriptor *iface, DWORD index,
2507 BOOL *selected, IMFStreamDescriptor **descriptor)
2509 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2511 TRACE("%p, %lu, %p, %p.\n", iface, index, selected, descriptor);
2513 if (index >= presentation_desc->count)
2514 return E_INVALIDARG;
2516 EnterCriticalSection(&presentation_desc->attributes.cs);
2517 *selected = presentation_desc->descriptors[index].selected;
2518 LeaveCriticalSection(&presentation_desc->attributes.cs);
2520 *descriptor = presentation_desc->descriptors[index].descriptor;
2521 IMFStreamDescriptor_AddRef(*descriptor);
2523 return S_OK;
2526 static HRESULT WINAPI presentation_descriptor_SelectStream(IMFPresentationDescriptor *iface, DWORD index)
2528 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2530 TRACE("%p, %lu.\n", iface, index);
2532 if (index >= presentation_desc->count)
2533 return E_INVALIDARG;
2535 EnterCriticalSection(&presentation_desc->attributes.cs);
2536 presentation_desc->descriptors[index].selected = TRUE;
2537 LeaveCriticalSection(&presentation_desc->attributes.cs);
2539 return S_OK;
2542 static HRESULT WINAPI presentation_descriptor_DeselectStream(IMFPresentationDescriptor *iface, DWORD index)
2544 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2546 TRACE("%p, %lu.\n", iface, index);
2548 if (index >= presentation_desc->count)
2549 return E_INVALIDARG;
2551 EnterCriticalSection(&presentation_desc->attributes.cs);
2552 presentation_desc->descriptors[index].selected = FALSE;
2553 LeaveCriticalSection(&presentation_desc->attributes.cs);
2555 return S_OK;
2558 static HRESULT WINAPI presentation_descriptor_Clone(IMFPresentationDescriptor *iface,
2559 IMFPresentationDescriptor **descriptor)
2561 struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface);
2562 struct presentation_desc *object;
2563 unsigned int i;
2565 TRACE("%p, %p.\n", iface, descriptor);
2567 if (!(object = calloc(1, sizeof(*object))))
2568 return E_OUTOFMEMORY;
2570 presentation_descriptor_init(object, presentation_desc->count);
2572 EnterCriticalSection(&presentation_desc->attributes.cs);
2574 for (i = 0; i < presentation_desc->count; ++i)
2576 object->descriptors[i] = presentation_desc->descriptors[i];
2577 IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor);
2580 attributes_CopyAllItems(&presentation_desc->attributes, (IMFAttributes *)&object->IMFPresentationDescriptor_iface);
2582 LeaveCriticalSection(&presentation_desc->attributes.cs);
2584 *descriptor = &object->IMFPresentationDescriptor_iface;
2586 return S_OK;
2589 static const IMFPresentationDescriptorVtbl presentationdescriptorvtbl =
2591 presentation_descriptor_QueryInterface,
2592 presentation_descriptor_AddRef,
2593 presentation_descriptor_Release,
2594 presentation_descriptor_GetItem,
2595 presentation_descriptor_GetItemType,
2596 presentation_descriptor_CompareItem,
2597 presentation_descriptor_Compare,
2598 presentation_descriptor_GetUINT32,
2599 presentation_descriptor_GetUINT64,
2600 presentation_descriptor_GetDouble,
2601 presentation_descriptor_GetGUID,
2602 presentation_descriptor_GetStringLength,
2603 presentation_descriptor_GetString,
2604 presentation_descriptor_GetAllocatedString,
2605 presentation_descriptor_GetBlobSize,
2606 presentation_descriptor_GetBlob,
2607 presentation_descriptor_GetAllocatedBlob,
2608 presentation_descriptor_GetUnknown,
2609 presentation_descriptor_SetItem,
2610 presentation_descriptor_DeleteItem,
2611 presentation_descriptor_DeleteAllItems,
2612 presentation_descriptor_SetUINT32,
2613 presentation_descriptor_SetUINT64,
2614 presentation_descriptor_SetDouble,
2615 presentation_descriptor_SetGUID,
2616 presentation_descriptor_SetString,
2617 presentation_descriptor_SetBlob,
2618 presentation_descriptor_SetUnknown,
2619 presentation_descriptor_LockStore,
2620 presentation_descriptor_UnlockStore,
2621 presentation_descriptor_GetCount,
2622 presentation_descriptor_GetItemByIndex,
2623 presentation_descriptor_CopyAllItems,
2624 presentation_descriptor_GetStreamDescriptorCount,
2625 presentation_descriptor_GetStreamDescriptorByIndex,
2626 presentation_descriptor_SelectStream,
2627 presentation_descriptor_DeselectStream,
2628 presentation_descriptor_Clone,
2631 static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count)
2633 HRESULT hr;
2635 if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
2636 return hr;
2637 object->IMFPresentationDescriptor_iface.lpVtbl = &presentationdescriptorvtbl;
2638 if (!(object->descriptors = calloc(count, sizeof(*object->descriptors))))
2640 IMFPresentationDescriptor_Release(&object->IMFPresentationDescriptor_iface);
2641 return E_OUTOFMEMORY;
2643 object->count = count;
2645 return S_OK;
2648 /***********************************************************************
2649 * MFCreatePresentationDescriptor (mfplat.@)
2651 HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor **descriptors,
2652 IMFPresentationDescriptor **out)
2654 struct presentation_desc *object;
2655 unsigned int i;
2656 HRESULT hr;
2658 TRACE("%lu, %p, %p.\n", count, descriptors, out);
2660 if (!count)
2661 return E_INVALIDARG;
2663 for (i = 0; i < count; ++i)
2665 if (!descriptors[i])
2666 return E_INVALIDARG;
2669 if (!(object = calloc(1, sizeof(*object))))
2670 return E_OUTOFMEMORY;
2672 if (FAILED(hr = presentation_descriptor_init(object, count)))
2674 free(object);
2675 return hr;
2678 for (i = 0; i < count; ++i)
2680 object->descriptors[i].descriptor = descriptors[i];
2681 IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor);
2684 *out = &object->IMFPresentationDescriptor_iface;
2686 return S_OK;
2689 struct uncompressed_video_format
2691 const GUID *subtype;
2692 unsigned char bpp;
2693 unsigned char alignment;
2694 unsigned char bottom_up;
2695 unsigned char yuv;
2696 int compression;
2699 static int __cdecl uncompressed_video_format_compare(const void *a, const void *b)
2701 const struct uncompressed_video_format *a_format = a, *b_format = b;
2702 return memcmp(a_format->subtype, b_format->subtype, sizeof(GUID));
2705 static struct uncompressed_video_format video_formats[] =
2707 { &MFVideoFormat_RGB1, 1, 0, 1, 0, BI_RGB },
2708 { &MFVideoFormat_RGB4, 4, 0, 1, 0, BI_RGB },
2709 { &MFVideoFormat_RGB24, 24, 3, 1, 0, BI_RGB },
2710 { &MFVideoFormat_ARGB32, 32, 3, 1, 0, BI_RGB },
2711 { &MFVideoFormat_RGB32, 32, 3, 1, 0, BI_RGB },
2712 { &MFVideoFormat_RGB565, 16, 3, 1, 0, BI_BITFIELDS },
2713 { &MFVideoFormat_RGB555, 16, 3, 1, 0, BI_RGB },
2714 { &MFVideoFormat_A2R10G10B10, 32, 3, 1, 0, -1 },
2715 { &MFVideoFormat_A2B10G10R10, 32, 3, 1, 0, -1 },
2716 { &MFVideoFormat_RGB8, 8, 3, 1, 0, BI_RGB },
2717 { &MFVideoFormat_L8, 8, 3, 1, 0, -1 },
2718 { &MFVideoFormat_AYUV, 32, 3, 0, 1, -1 },
2719 { &MFVideoFormat_I420, 12, 0, 0, 1, -1 },
2720 { &MFVideoFormat_IMC1, 16, 3, 0, 1, -1 },
2721 { &MFVideoFormat_IMC2, 12, 0, 0, 1, -1 },
2722 { &MFVideoFormat_IMC3, 16, 3, 0, 1, -1 },
2723 { &MFVideoFormat_IMC4, 12, 0, 0, 1, -1 },
2724 { &MFVideoFormat_IYUV, 12, 0, 0, 1, -1 },
2725 { &MFVideoFormat_NV11, 12, 0, 0, 1, -1 },
2726 { &MFVideoFormat_NV12, 12, 0, 0, 1, -1 },
2727 { &MFVideoFormat_D16, 16, 3, 0, 0, -1 },
2728 { &MFVideoFormat_L16, 16, 3, 0, 0, -1 },
2729 { &MFVideoFormat_UYVY, 16, 0, 0, 1, -1 },
2730 { &MFVideoFormat_YUY2, 16, 0, 0, 1, -1 },
2731 { &MFVideoFormat_YV12, 12, 0, 0, 1, -1 },
2732 { &MFVideoFormat_YVYU, 16, 0, 0, 1, -1 },
2733 { &MFVideoFormat_A16B16G16R16F, 64, 3, 1, 0, -1 },
2734 { &MEDIASUBTYPE_RGB8, 8, 3, 1, 0, BI_RGB },
2735 { &MEDIASUBTYPE_RGB565, 16, 3, 1, 0, BI_BITFIELDS },
2736 { &MEDIASUBTYPE_RGB555, 16, 3, 1, 0, BI_RGB },
2737 { &MEDIASUBTYPE_RGB24, 24, 3, 1, 0, BI_RGB },
2738 { &MEDIASUBTYPE_RGB32, 32, 3, 1, 0, BI_RGB },
2741 static BOOL WINAPI mf_video_formats_init(INIT_ONCE *once, void *param, void **context)
2743 qsort(video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats), uncompressed_video_format_compare);
2744 return TRUE;
2747 static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype)
2749 static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
2750 struct uncompressed_video_format key = {.subtype = subtype};
2752 InitOnceExecuteOnce(&init_once, mf_video_formats_init, NULL, NULL);
2754 return bsearch(&key, video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats),
2755 uncompressed_video_format_compare);
2758 static unsigned int mf_get_stride_for_format(const struct uncompressed_video_format *format, unsigned int width)
2760 if (format->bpp < 8) return (width * format->bpp) / 8;
2761 return (width * (format->bpp / 8) + format->alignment) & ~format->alignment;
2764 unsigned int mf_format_get_stride(const GUID *subtype, unsigned int width, BOOL *is_yuv)
2766 struct uncompressed_video_format *format = mf_get_video_format(subtype);
2768 if (format)
2770 *is_yuv = format->yuv;
2771 return mf_get_stride_for_format(format, width);
2774 return 0;
2777 /***********************************************************************
2778 * MFGetStrideForBitmapInfoHeader (mfplat.@)
2780 HRESULT WINAPI MFGetStrideForBitmapInfoHeader(DWORD fourcc, DWORD width, LONG *stride)
2782 struct uncompressed_video_format *format;
2783 GUID subtype;
2785 TRACE("%s, %lu, %p.\n", mf_debugstr_fourcc(fourcc), width, stride);
2787 memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
2788 subtype.Data1 = fourcc;
2790 if (!(format = mf_get_video_format(&subtype)))
2792 *stride = 0;
2793 return MF_E_INVALIDMEDIATYPE;
2796 *stride = mf_get_stride_for_format(format, width);
2797 if (format->bottom_up)
2798 *stride *= -1;
2800 return S_OK;
2803 /***********************************************************************
2804 * MFCalculateImageSize (mfplat.@)
2806 HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size)
2808 struct uncompressed_video_format *format;
2809 unsigned int stride;
2811 TRACE("%s, %u, %u, %p.\n", debugstr_mf_guid(subtype), width, height, size);
2813 if (!(format = mf_get_video_format(subtype)))
2815 *size = 0;
2816 return E_INVALIDARG;
2819 switch (subtype->Data1)
2821 case MAKEFOURCC('I','M','C','2'):
2822 case MAKEFOURCC('I','M','C','4'):
2823 case MAKEFOURCC('N','V','1','2'):
2824 case MAKEFOURCC('Y','V','1','2'):
2825 case MAKEFOURCC('I','4','2','0'):
2826 case MAKEFOURCC('I','Y','U','V'):
2827 /* 2 x 2 block, interleaving UV for half the height */
2828 *size = ((width + 1) & ~1) * height * 3 / 2;
2829 break;
2830 case MAKEFOURCC('N','V','1','1'):
2831 *size = ((width + 3) & ~3) * height * 3 / 2;
2832 break;
2833 case D3DFMT_L8:
2834 case D3DFMT_L16:
2835 case D3DFMT_D16:
2836 *size = width * (format->bpp / 8) * height;
2837 break;
2838 default:
2839 stride = mf_get_stride_for_format(format, width);
2840 *size = stride * height;
2843 return S_OK;
2846 /***********************************************************************
2847 * MFGetPlaneSize (mfplat.@)
2849 HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *size)
2851 struct uncompressed_video_format *format;
2852 unsigned int stride;
2853 GUID subtype;
2855 TRACE("%s, %lu, %lu, %p.\n", mf_debugstr_fourcc(fourcc), width, height, size);
2857 memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
2858 subtype.Data1 = fourcc;
2860 if ((format = mf_get_video_format(&subtype)))
2861 stride = mf_get_stride_for_format(format, width);
2862 else
2863 stride = 0;
2865 switch (fourcc)
2867 case MAKEFOURCC('I','M','C','2'):
2868 case MAKEFOURCC('I','M','C','4'):
2869 case MAKEFOURCC('N','V','1','2'):
2870 case MAKEFOURCC('Y','V','1','2'):
2871 case MAKEFOURCC('I','4','2','0'):
2872 case MAKEFOURCC('I','Y','U','V'):
2873 case MAKEFOURCC('N','V','1','1'):
2874 *size = stride * height * 3 / 2;
2875 break;
2876 default:
2877 *size = stride * height;
2880 return S_OK;
2883 /***********************************************************************
2884 * MFCompareFullToPartialMediaType (mfplat.@)
2886 BOOL WINAPI MFCompareFullToPartialMediaType(IMFMediaType *full_type, IMFMediaType *partial_type)
2888 BOOL result;
2889 GUID major;
2891 TRACE("%p, %p.\n", full_type, partial_type);
2893 if (FAILED(IMFMediaType_GetMajorType(partial_type, &major)))
2894 return FALSE;
2896 if (FAILED(IMFMediaType_Compare(partial_type, (IMFAttributes *)full_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result)))
2897 return FALSE;
2899 return result;
2902 /***********************************************************************
2903 * MFWrapMediaType (mfplat.@)
2905 HRESULT WINAPI MFWrapMediaType(IMFMediaType *original, REFGUID major, REFGUID subtype, IMFMediaType **ret)
2907 IMFMediaType *mediatype;
2908 UINT8 *buffer;
2909 UINT32 size;
2910 HRESULT hr;
2912 TRACE("%p, %s, %s, %p.\n", original, debugstr_guid(major), debugstr_guid(subtype), ret);
2914 if (FAILED(hr = MFGetAttributesAsBlobSize((IMFAttributes *)original, &size)))
2915 return hr;
2917 if (!(buffer = malloc(size)))
2918 return E_OUTOFMEMORY;
2920 if (FAILED(hr = MFGetAttributesAsBlob((IMFAttributes *)original, buffer, size)))
2921 goto failed;
2923 if (FAILED(hr = MFCreateMediaType(&mediatype)))
2924 goto failed;
2926 if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major)))
2927 goto failed;
2929 if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, subtype)))
2930 goto failed;
2932 if (FAILED(hr = IMFMediaType_SetBlob(mediatype, &MF_MT_WRAPPED_TYPE, buffer, size)))
2933 goto failed;
2935 *ret = mediatype;
2937 failed:
2938 free(buffer);
2940 return hr;
2943 /***********************************************************************
2944 * MFUnwrapMediaType (mfplat.@)
2946 HRESULT WINAPI MFUnwrapMediaType(IMFMediaType *wrapper, IMFMediaType **ret)
2948 IMFMediaType *mediatype;
2949 UINT8 *buffer;
2950 UINT32 size;
2951 HRESULT hr;
2953 TRACE("%p, %p.\n", wrapper, ret);
2955 if (FAILED(hr = MFCreateMediaType(&mediatype)))
2956 return hr;
2958 if (FAILED(hr = IMFMediaType_GetAllocatedBlob(wrapper, &MF_MT_WRAPPED_TYPE, &buffer, &size)))
2960 IMFMediaType_Release(mediatype);
2961 return hr;
2964 hr = MFInitAttributesFromBlob((IMFAttributes *)mediatype, buffer, size);
2965 CoTaskMemFree(buffer);
2966 if (FAILED(hr))
2967 return hr;
2969 *ret = mediatype;
2971 return S_OK;
2974 /***********************************************************************
2975 * MFCreateWaveFormatExFromMFMediaType (mfplat.@)
2977 HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVEFORMATEX **ret_format,
2978 UINT32 *size, UINT32 flags)
2980 UINT32 value, extra_size = 0, user_size;
2981 WAVEFORMATEX *format;
2982 GUID major, subtype;
2983 void *user_data;
2984 HRESULT hr;
2986 TRACE("%p, %p, %p, %#x.\n", mediatype, ret_format, size, flags);
2988 if (FAILED(hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &major)))
2989 return hr;
2991 if (FAILED(hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &subtype)))
2992 return hr;
2994 if (!IsEqualGUID(&major, &MFMediaType_Audio))
2995 return E_INVALIDARG;
2997 if (FAILED(hr = IMFMediaType_GetBlobSize(mediatype, &MF_MT_USER_DATA, &user_size)))
2999 if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
3000 return hr;
3001 user_size = 0;
3004 if (flags == MFWaveFormatExConvertFlag_ForceExtensible)
3005 extra_size = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(*format);
3007 *size = sizeof(*format) + user_size + extra_size;
3008 if (!(format = CoTaskMemAlloc(*size)))
3009 return E_OUTOFMEMORY;
3011 memset(format, 0, *size);
3012 format->wFormatTag = subtype.Data1;
3013 format->cbSize = user_size + extra_size;
3014 user_data = format + 1;
3016 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value)))
3017 format->nChannels = value;
3018 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value)))
3019 format->nSamplesPerSec = value;
3020 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value)))
3021 format->nAvgBytesPerSec = value;
3022 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value)))
3023 format->nBlockAlign = value;
3024 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value)))
3025 format->wBitsPerSample = value;
3027 if (flags == MFWaveFormatExConvertFlag_ForceExtensible)
3029 WAVEFORMATEXTENSIBLE *format_ext = CONTAINING_RECORD(format, WAVEFORMATEXTENSIBLE, Format);
3031 format_ext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3032 format_ext->SubFormat = subtype;
3033 user_data = format_ext + 1;
3035 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value)))
3036 format_ext->Samples.wSamplesPerBlock = value;
3038 if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value)))
3039 format_ext->dwChannelMask = value;
3040 else if (format_ext->Format.nChannels < ARRAY_SIZE(default_channel_mask))
3041 format_ext->dwChannelMask = default_channel_mask[format_ext->Format.nChannels];
3044 IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, user_data, user_size, NULL);
3046 *ret_format = format;
3048 return S_OK;
3051 static void mediatype_set_uint32(IMFMediaType *mediatype, const GUID *attr, unsigned int value, HRESULT *hr)
3053 if (SUCCEEDED(*hr))
3054 *hr = IMFMediaType_SetUINT32(mediatype, attr, value);
3057 static void mediatype_set_uint64(IMFMediaType *mediatype, const GUID *attr, unsigned int high, unsigned int low, HRESULT *hr)
3059 if (SUCCEEDED(*hr))
3060 *hr = IMFMediaType_SetUINT64(mediatype, attr, (UINT64)high << 32 | low);
3063 static void mediatype_set_guid(IMFMediaType *mediatype, const GUID *attr, const GUID *value, HRESULT *hr)
3065 if (SUCCEEDED(*hr))
3066 *hr = IMFMediaType_SetGUID(mediatype, attr, value);
3069 static void mediatype_set_blob(IMFMediaType *mediatype, const GUID *attr, const UINT8 *data,
3070 unsigned int size, HRESULT *hr)
3072 if (SUCCEEDED(*hr))
3073 *hr = IMFMediaType_SetBlob(mediatype, attr, data, size);
3076 /***********************************************************************
3077 * MFInitMediaTypeFromWaveFormatEx (mfplat.@)
3079 HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size)
3081 const WAVEFORMATEXTENSIBLE *wfex = (const WAVEFORMATEXTENSIBLE *)format;
3082 GUID subtype;
3083 HRESULT hr;
3085 TRACE("%p, %p, %u.\n", mediatype, format, size);
3087 if (!mediatype || !format)
3088 return E_POINTER;
3090 if (format->cbSize + sizeof(*format) > size)
3091 return E_INVALIDARG;
3093 hr = IMFMediaType_DeleteAllItems(mediatype);
3095 mediatype_set_guid(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio, &hr);
3097 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
3099 memcpy(&subtype, &wfex->SubFormat, sizeof(subtype));
3101 if (wfex->dwChannelMask)
3102 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, wfex->dwChannelMask, &hr);
3104 if (format->wBitsPerSample && wfex->Samples.wValidBitsPerSample)
3105 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, wfex->Samples.wValidBitsPerSample, &hr);
3107 else
3109 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
3110 subtype.Data1 = format->wFormatTag;
3112 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr);
3114 mediatype_set_guid(mediatype, &MF_MT_SUBTYPE, &subtype, &hr);
3116 if (format->nChannels)
3117 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, format->nChannels, &hr);
3119 if (format->nSamplesPerSec)
3120 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->nSamplesPerSec, &hr);
3122 if (format->nAvgBytesPerSec)
3123 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, format->nAvgBytesPerSec, &hr);
3125 if (format->nBlockAlign)
3126 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->nBlockAlign, &hr);
3128 if (format->wBitsPerSample)
3129 mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, format->wBitsPerSample, &hr);
3131 if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) ||
3132 IsEqualGUID(&subtype, &MFAudioFormat_Float))
3134 mediatype_set_uint32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr);
3137 if (IsEqualGUID(&subtype, &MFAudioFormat_AAC))
3139 HEAACWAVEINFO *info = CONTAINING_RECORD(format, HEAACWAVEINFO, wfx);
3140 if (format->cbSize < sizeof(HEAACWAVEINFO) - sizeof(WAVEFORMATEX))
3141 return E_INVALIDARG;
3142 mediatype_set_uint32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, info->wAudioProfileLevelIndication, &hr);
3143 mediatype_set_uint32(mediatype, &MF_MT_AAC_PAYLOAD_TYPE, info->wPayloadType, &hr);
3146 if (format->cbSize && format->wFormatTag != WAVE_FORMAT_EXTENSIBLE)
3147 mediatype_set_blob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)(format + 1), format->cbSize, &hr);
3149 return hr;
3152 /***********************************************************************
3153 * MFCreateVideoMediaTypeFromSubtype (mfplat.@)
3155 HRESULT WINAPI MFCreateVideoMediaTypeFromSubtype(const GUID *subtype, IMFVideoMediaType **media_type)
3157 struct media_type *object;
3158 HRESULT hr;
3160 TRACE("%s, %p.\n", debugstr_guid(subtype), media_type);
3162 if (!media_type)
3163 return E_INVALIDARG;
3165 if (FAILED(hr = create_media_type(&object)))
3166 return hr;
3168 IMFMediaType_SetGUID(&object->IMFMediaType_iface, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3169 IMFMediaType_SetGUID(&object->IMFMediaType_iface, &MF_MT_SUBTYPE, subtype);
3171 *media_type = &object->IMFVideoMediaType_iface;
3173 return S_OK;
3176 /***********************************************************************
3177 * MFCreateAudioMediaType (mfplat.@)
3179 HRESULT WINAPI MFCreateAudioMediaType(const WAVEFORMATEX *format, IMFAudioMediaType **media_type)
3181 struct media_type *object;
3182 HRESULT hr;
3184 TRACE("%p, %p.\n", format, media_type);
3186 if (!media_type)
3187 return E_INVALIDARG;
3189 if (FAILED(hr = create_media_type(&object)))
3190 return hr;
3192 if (FAILED(hr = MFInitMediaTypeFromWaveFormatEx(&object->IMFMediaType_iface, format, sizeof(*format) + format->cbSize)))
3194 IMFMediaType_Release(&object->IMFMediaType_iface);
3195 return hr;
3198 *media_type = &object->IMFAudioMediaType_iface;
3200 return S_OK;
3203 static void media_type_get_ratio(IMFMediaType *media_type, const GUID *attr, DWORD *numerator,
3204 DWORD *denominator)
3206 UINT64 value;
3208 if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, attr, &value)))
3210 *numerator = value >> 32;
3211 *denominator = value;
3215 /***********************************************************************
3216 * MFCreateAMMediaTypeFromMFMediaType (mfplat.@)
3218 HRESULT WINAPI MFCreateAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE **am_type)
3220 AM_MEDIA_TYPE *mt;
3221 HRESULT hr;
3223 TRACE("%p, %s, %p.\n", media_type, debugstr_mf_guid(&format), am_type);
3225 *am_type = NULL;
3226 if (!(mt = CoTaskMemAlloc(sizeof(*mt))))
3227 return E_OUTOFMEMORY;
3228 if (FAILED(hr = MFInitAMMediaTypeFromMFMediaType(media_type, format, mt)))
3230 CoTaskMemFree(mt);
3231 return hr;
3234 *am_type = mt;
3235 return hr;
3238 static UINT32 media_type_get_uint32(IMFMediaType *media_type, REFGUID guid)
3240 UINT32 value;
3241 return SUCCEEDED(IMFMediaType_GetUINT32(media_type, guid, &value)) ? value : 0;
3244 /***********************************************************************
3245 * MFCreateMFVideoFormatFromMFMediaType (mfplat.@)
3247 HRESULT WINAPI MFCreateMFVideoFormatFromMFMediaType(IMFMediaType *media_type, MFVIDEOFORMAT **video_format, UINT32 *size)
3249 UINT32 palette_size = 0;
3250 MFVIDEOFORMAT *format;
3251 INT32 stride;
3252 GUID guid;
3254 TRACE("%p, %p, %p.\n", media_type, video_format, size);
3256 *size = sizeof(*format);
3258 if (SUCCEEDED(IMFMediaType_GetBlobSize(media_type, &MF_MT_PALETTE, &palette_size)))
3259 *size += palette_size;
3261 if (!(format = CoTaskMemAlloc(*size)))
3262 return E_OUTOFMEMORY;
3264 *video_format = format;
3266 memset(format, 0, sizeof(*format));
3267 format->dwSize = *size;
3269 if (SUCCEEDED(IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid)))
3271 memcpy(&format->guidFormat, &guid, sizeof(guid));
3272 format->surfaceInfo.Format = guid.Data1;
3275 media_type_get_ratio(media_type, &MF_MT_FRAME_SIZE, &format->videoInfo.dwWidth, &format->videoInfo.dwHeight);
3276 media_type_get_ratio(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &format->videoInfo.PixelAspectRatio.Numerator,
3277 &format->videoInfo.PixelAspectRatio.Denominator);
3278 media_type_get_ratio(media_type, &MF_MT_FRAME_RATE, &format->videoInfo.FramesPerSecond.Numerator,
3279 &format->videoInfo.FramesPerSecond.Denominator);
3281 format->videoInfo.SourceChromaSubsampling = media_type_get_uint32(media_type, &MF_MT_VIDEO_CHROMA_SITING);
3282 format->videoInfo.InterlaceMode = media_type_get_uint32(media_type, &MF_MT_INTERLACE_MODE);
3283 format->videoInfo.TransferFunction = media_type_get_uint32(media_type, &MF_MT_TRANSFER_FUNCTION);
3284 format->videoInfo.ColorPrimaries = media_type_get_uint32(media_type, &MF_MT_VIDEO_PRIMARIES);
3285 format->videoInfo.TransferMatrix = media_type_get_uint32(media_type, &MF_MT_YUV_MATRIX);
3286 format->videoInfo.SourceLighting = media_type_get_uint32(media_type, &MF_MT_VIDEO_LIGHTING);
3287 format->videoInfo.NominalRange = media_type_get_uint32(media_type, &MF_MT_VIDEO_NOMINAL_RANGE);
3288 IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&format->videoInfo.GeometricAperture,
3289 sizeof(format->videoInfo.GeometricAperture), NULL);
3290 IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 *)&format->videoInfo.MinimumDisplayAperture,
3291 sizeof(format->videoInfo.MinimumDisplayAperture), NULL);
3293 /* Video flags. */
3294 format->videoInfo.VideoFlags |= media_type_get_uint32(media_type, &MF_MT_PAD_CONTROL_FLAGS);
3295 format->videoInfo.VideoFlags |= media_type_get_uint32(media_type, &MF_MT_SOURCE_CONTENT_HINT);
3296 format->videoInfo.VideoFlags |= media_type_get_uint32(media_type, &MF_MT_DRM_FLAGS);
3297 if (media_type_get_uint32(media_type, &MF_MT_PAN_SCAN_ENABLED))
3299 format->videoInfo.VideoFlags |= MFVideoFlag_PanScanEnabled;
3300 IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, (UINT8 *)&format->videoInfo.PanScanAperture,
3301 sizeof(format->videoInfo.PanScanAperture), NULL);
3303 stride = media_type_get_uint32(media_type, &MF_MT_DEFAULT_STRIDE);
3304 if (stride < 0)
3305 format->videoInfo.VideoFlags |= MFVideoFlag_BottomUpLinearRep;
3307 format->compressedInfo.AvgBitrate = media_type_get_uint32(media_type, &MF_MT_AVG_BITRATE);
3308 format->compressedInfo.AvgBitErrorRate = media_type_get_uint32(media_type, &MF_MT_AVG_BIT_ERROR_RATE);
3309 format->compressedInfo.MaxKeyFrameSpacing = media_type_get_uint32(media_type, &MF_MT_MAX_KEYFRAME_SPACING);
3311 /* Palette. */
3312 if (palette_size)
3314 format->surfaceInfo.PaletteEntries = palette_size / sizeof(*format->surfaceInfo.Palette);
3315 IMFMediaType_GetBlob(media_type, &MF_MT_PALETTE, (UINT8 *)format->surfaceInfo.Palette, palette_size, NULL);
3318 return S_OK;
3321 /***********************************************************************
3322 * MFConvertColorInfoToDXVA (mfplat.@)
3324 HRESULT WINAPI MFConvertColorInfoToDXVA(DWORD *dxva_info, const MFVIDEOFORMAT *format)
3326 struct
3328 UINT SampleFormat : 8;
3329 UINT VideoChromaSubsampling : 4;
3330 UINT NominalRange : 3;
3331 UINT VideoTransferMatrix : 3;
3332 UINT VideoLighting : 4;
3333 UINT VideoPrimaries : 5;
3334 UINT VideoTransferFunction : 5;
3335 } *dxva_format = (void *)dxva_info;
3337 TRACE("%p, %p.\n", dxva_info, format);
3339 if (format->videoInfo.InterlaceMode == MFVideoInterlace_MixedInterlaceOrProgressive)
3340 dxva_format->SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
3341 else
3342 dxva_format->SampleFormat = format->videoInfo.InterlaceMode;
3344 dxva_format->VideoChromaSubsampling = format->videoInfo.SourceChromaSubsampling;
3345 dxva_format->NominalRange = format->videoInfo.NominalRange;
3346 dxva_format->VideoTransferMatrix = format->videoInfo.TransferMatrix;
3347 dxva_format->VideoLighting = format->videoInfo.SourceLighting;
3348 dxva_format->VideoPrimaries = format->videoInfo.ColorPrimaries;
3349 dxva_format->VideoTransferFunction = format->videoInfo.TransferFunction;
3351 return S_OK;
3354 struct frame_rate
3356 UINT64 time;
3357 UINT64 rate;
3360 static const struct frame_rate known_rates[] =
3362 #define KNOWN_RATE(ft,n,d) { ft, ((UINT64)n << 32) | d }
3363 KNOWN_RATE(417188, 24000, 1001),
3364 KNOWN_RATE(416667, 24, 1),
3365 KNOWN_RATE(400000, 25, 1),
3366 KNOWN_RATE(333667, 30000, 1001),
3367 KNOWN_RATE(333333, 30, 1),
3368 KNOWN_RATE(200000, 50, 1),
3369 KNOWN_RATE(166833, 60000, 1001),
3370 KNOWN_RATE(166667, 60, 1),
3371 #undef KNOWN_RATE
3374 static const struct frame_rate *known_rate_from_rate(UINT64 rate)
3376 UINT i;
3377 for (i = 0; i < ARRAY_SIZE(known_rates); i++)
3379 if (rate == known_rates[i].rate)
3380 return known_rates + i;
3382 return NULL;
3385 static const struct frame_rate *known_rate_from_time(UINT64 time)
3387 UINT i;
3388 for (i = 0; i < ARRAY_SIZE(known_rates); i++)
3390 if (time >= known_rates[i].time - 30
3391 && time <= known_rates[i].time + 30)
3392 return known_rates + i;
3394 return NULL;
3397 /***********************************************************************
3398 * MFFrameRateToAverageTimePerFrame (mfplat.@)
3400 HRESULT WINAPI MFFrameRateToAverageTimePerFrame(UINT32 numerator, UINT32 denominator, UINT64 *avgframetime)
3402 UINT64 rate = ((UINT64)numerator << 32) | denominator;
3403 const struct frame_rate *entry;
3405 TRACE("%u, %u, %p.\n", numerator, denominator, avgframetime);
3407 if ((entry = known_rate_from_rate(rate)))
3408 *avgframetime = entry->time;
3409 else
3410 *avgframetime = numerator ? denominator * (UINT64)10000000 / numerator : 0;
3412 return S_OK;
3415 static unsigned int get_gcd(unsigned int a, unsigned int b)
3417 unsigned int m;
3419 while (b)
3421 m = a % b;
3422 a = b;
3423 b = m;
3426 return a;
3429 /***********************************************************************
3430 * MFAverageTimePerFrameToFrameRate (mfplat.@)
3432 HRESULT WINAPI MFAverageTimePerFrameToFrameRate(UINT64 avgtime, UINT32 *numerator, UINT32 *denominator)
3434 const struct frame_rate *entry;
3435 unsigned int gcd;
3437 TRACE("%s, %p, %p.\n", wine_dbgstr_longlong(avgtime), numerator, denominator);
3439 if ((entry = known_rate_from_time(avgtime)))
3441 *numerator = entry->rate >> 32;
3442 *denominator = entry->rate;
3444 else if (avgtime)
3446 if (avgtime > 100000000) avgtime = 100000000;
3447 gcd = get_gcd(10000000, avgtime);
3448 *numerator = 10000000 / gcd;
3449 *denominator = avgtime / gcd;
3451 else
3453 *numerator = *denominator = 0;
3456 return S_OK;
3459 /***********************************************************************
3460 * MFMapDXGIFormatToDX9Format (mfplat.@)
3462 DWORD WINAPI MFMapDXGIFormatToDX9Format(DXGI_FORMAT dxgi_format)
3464 switch (dxgi_format)
3466 case DXGI_FORMAT_R32G32B32A32_FLOAT:
3467 return D3DFMT_A32B32G32R32F;
3468 case DXGI_FORMAT_R16G16B16A16_FLOAT:
3469 return D3DFMT_A16B16G16R16F;
3470 case DXGI_FORMAT_R16G16B16A16_UNORM:
3471 return D3DFMT_A16B16G16R16;
3472 case DXGI_FORMAT_R16G16B16A16_SNORM:
3473 return D3DFMT_Q16W16V16U16;
3474 case DXGI_FORMAT_R32G32_FLOAT:
3475 return D3DFMT_G32R32F;
3476 case DXGI_FORMAT_R10G10B10A2_UNORM:
3477 return D3DFMT_A2B10G10R10;
3478 case DXGI_FORMAT_R8G8B8A8_SNORM:
3479 return D3DFMT_Q8W8V8U8;
3480 case DXGI_FORMAT_R16G16_FLOAT:
3481 return D3DFMT_G16R16F;
3482 case DXGI_FORMAT_R16G16_UNORM:
3483 return D3DFMT_G16R16;
3484 case DXGI_FORMAT_R16G16_SNORM:
3485 return D3DFMT_V16U16;
3486 case DXGI_FORMAT_D32_FLOAT:
3487 return D3DFMT_D32F_LOCKABLE;
3488 case DXGI_FORMAT_R32_FLOAT:
3489 return D3DFMT_R32F;
3490 case DXGI_FORMAT_D24_UNORM_S8_UINT:
3491 return D3DFMT_D24S8;
3492 case DXGI_FORMAT_R8G8_SNORM:
3493 return D3DFMT_V8U8;
3494 case DXGI_FORMAT_R16_FLOAT:
3495 return D3DFMT_R16F;
3496 case DXGI_FORMAT_D16_UNORM:
3497 return D3DFMT_D16_LOCKABLE;
3498 case DXGI_FORMAT_R16_UNORM:
3499 return D3DFMT_L16;
3500 case DXGI_FORMAT_R8_UNORM:
3501 return D3DFMT_L8;
3502 case DXGI_FORMAT_A8_UNORM:
3503 return D3DFMT_A8;
3504 case DXGI_FORMAT_BC1_UNORM:
3505 case DXGI_FORMAT_BC1_UNORM_SRGB:
3506 return D3DFMT_DXT1;
3507 case DXGI_FORMAT_BC2_UNORM:
3508 case DXGI_FORMAT_BC2_UNORM_SRGB:
3509 return D3DFMT_DXT2;
3510 case DXGI_FORMAT_BC3_UNORM:
3511 case DXGI_FORMAT_BC3_UNORM_SRGB:
3512 return D3DFMT_DXT4;
3513 case DXGI_FORMAT_R8G8B8A8_UNORM:
3514 return D3DFMT_A8B8G8R8;
3515 case DXGI_FORMAT_B8G8R8A8_UNORM:
3516 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
3517 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
3518 return D3DFMT_A8R8G8B8;
3519 case DXGI_FORMAT_B8G8R8X8_UNORM:
3520 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
3521 return D3DFMT_X8R8G8B8;
3522 case DXGI_FORMAT_AYUV:
3523 return MAKEFOURCC('A','Y','U','V');
3524 case DXGI_FORMAT_Y410:
3525 return MAKEFOURCC('Y','4','1','0');
3526 case DXGI_FORMAT_Y416:
3527 return MAKEFOURCC('Y','4','1','6');
3528 case DXGI_FORMAT_NV12:
3529 return MAKEFOURCC('N','V','1','2');
3530 case DXGI_FORMAT_P010:
3531 return MAKEFOURCC('P','0','1','0');
3532 case DXGI_FORMAT_P016:
3533 return MAKEFOURCC('P','0','1','6');
3534 case DXGI_FORMAT_420_OPAQUE:
3535 return MAKEFOURCC('4','2','0','O');
3536 case DXGI_FORMAT_YUY2:
3537 return D3DFMT_YUY2;
3538 case DXGI_FORMAT_Y210:
3539 return MAKEFOURCC('Y','2','1','0');
3540 case DXGI_FORMAT_Y216:
3541 return MAKEFOURCC('Y','2','1','6');
3542 case DXGI_FORMAT_NV11:
3543 return MAKEFOURCC('N','V','1','1');
3544 case DXGI_FORMAT_AI44:
3545 return MAKEFOURCC('A','I','4','4');
3546 case DXGI_FORMAT_IA44:
3547 return MAKEFOURCC('I','A','4','4');
3548 case DXGI_FORMAT_P8:
3549 return D3DFMT_P8;
3550 case DXGI_FORMAT_A8P8:
3551 return D3DFMT_A8P8;
3552 default:
3553 return 0;
3557 /***********************************************************************
3558 * MFMapDX9FormatToDXGIFormat (mfplat.@)
3560 DXGI_FORMAT WINAPI MFMapDX9FormatToDXGIFormat(DWORD format)
3562 switch (format)
3564 case D3DFMT_A32B32G32R32F:
3565 return DXGI_FORMAT_R32G32B32A32_FLOAT;
3566 case D3DFMT_A16B16G16R16F:
3567 return DXGI_FORMAT_R16G16B16A16_FLOAT;
3568 case D3DFMT_A16B16G16R16:
3569 return DXGI_FORMAT_R16G16B16A16_UNORM;
3570 case D3DFMT_Q16W16V16U16:
3571 return DXGI_FORMAT_R16G16B16A16_SNORM;
3572 case D3DFMT_G32R32F:
3573 return DXGI_FORMAT_R32G32_FLOAT;
3574 case D3DFMT_A2B10G10R10:
3575 return DXGI_FORMAT_R10G10B10A2_UNORM;
3576 case D3DFMT_Q8W8V8U8:
3577 return DXGI_FORMAT_R8G8B8A8_SNORM;
3578 case D3DFMT_G16R16F:
3579 return DXGI_FORMAT_R16G16_FLOAT;
3580 case D3DFMT_G16R16:
3581 return DXGI_FORMAT_R16G16_UNORM;
3582 case D3DFMT_V16U16:
3583 return DXGI_FORMAT_R16G16_SNORM;
3584 case D3DFMT_D32F_LOCKABLE:
3585 return DXGI_FORMAT_D32_FLOAT;
3586 case D3DFMT_R32F:
3587 return DXGI_FORMAT_R32_FLOAT;
3588 case D3DFMT_D24S8:
3589 return DXGI_FORMAT_D24_UNORM_S8_UINT;
3590 case D3DFMT_V8U8:
3591 return DXGI_FORMAT_R8G8_SNORM;
3592 case D3DFMT_R16F:
3593 return DXGI_FORMAT_R16_FLOAT;
3594 case D3DFMT_L16:
3595 return DXGI_FORMAT_R16_UNORM;
3596 case D3DFMT_L8:
3597 return DXGI_FORMAT_R8_UNORM;
3598 case D3DFMT_A8:
3599 return DXGI_FORMAT_A8_UNORM;
3600 case D3DFMT_DXT1:
3601 return DXGI_FORMAT_BC1_UNORM;
3602 case D3DFMT_DXT2:
3603 return DXGI_FORMAT_BC2_UNORM;
3604 case D3DFMT_DXT4:
3605 return DXGI_FORMAT_BC3_UNORM;
3606 case D3DFMT_A8R8G8B8:
3607 return DXGI_FORMAT_B8G8R8A8_UNORM;
3608 case D3DFMT_X8R8G8B8:
3609 return DXGI_FORMAT_B8G8R8X8_UNORM;
3610 case MAKEFOURCC('A','Y','U','V'):
3611 return DXGI_FORMAT_AYUV;
3612 case MAKEFOURCC('Y','4','1','0'):
3613 return DXGI_FORMAT_Y410;
3614 case MAKEFOURCC('Y','4','1','6'):
3615 return DXGI_FORMAT_Y416;
3616 case MAKEFOURCC('N','V','1','2'):
3617 return DXGI_FORMAT_NV12;
3618 case MAKEFOURCC('P','0','1','0'):
3619 return DXGI_FORMAT_P010;
3620 case MAKEFOURCC('P','0','1','6'):
3621 return DXGI_FORMAT_P016;
3622 case MAKEFOURCC('4','2','0','O'):
3623 return DXGI_FORMAT_420_OPAQUE;
3624 case D3DFMT_YUY2:
3625 return DXGI_FORMAT_YUY2;
3626 case MAKEFOURCC('Y','2','1','0'):
3627 return DXGI_FORMAT_Y210;
3628 case MAKEFOURCC('Y','2','1','6'):
3629 return DXGI_FORMAT_Y216;
3630 case MAKEFOURCC('N','V','1','1'):
3631 return DXGI_FORMAT_NV11;
3632 case MAKEFOURCC('A','I','4','4'):
3633 return DXGI_FORMAT_AI44;
3634 case MAKEFOURCC('I','A','4','4'):
3635 return DXGI_FORMAT_IA44;
3636 case D3DFMT_P8:
3637 return DXGI_FORMAT_P8;
3638 case D3DFMT_A8P8:
3639 return DXGI_FORMAT_A8P8;
3640 default:
3641 return DXGI_FORMAT_UNKNOWN;
3645 /***********************************************************************
3646 * MFInitVideoFormat_RGB (mfplat.@)
3648 HRESULT WINAPI MFInitVideoFormat_RGB(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat)
3650 unsigned int transfer_function;
3652 TRACE("%p, %lu, %lu, %#lx.\n", format, width, height, d3dformat);
3654 if (!format)
3655 return E_INVALIDARG;
3657 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
3659 switch (d3dformat)
3661 case D3DFMT_X8R8G8B8:
3662 case D3DFMT_R8G8B8:
3663 case D3DFMT_A8R8G8B8:
3664 case D3DFMT_R5G6B5:
3665 case D3DFMT_X1R5G5B5:
3666 case D3DFMT_A2B10G10R10:
3667 case D3DFMT_A2R10G10B10:
3668 case D3DFMT_P8:
3669 transfer_function = MFVideoTransFunc_sRGB;
3670 break;
3671 default:
3672 transfer_function = MFVideoTransFunc_10;
3675 memset(format, 0, sizeof(*format));
3676 format->dwSize = sizeof(*format);
3677 format->videoInfo.dwWidth = width;
3678 format->videoInfo.dwHeight = height;
3679 format->videoInfo.PixelAspectRatio.Numerator = 1;
3680 format->videoInfo.PixelAspectRatio.Denominator = 1;
3681 format->videoInfo.InterlaceMode = MFVideoInterlace_Progressive;
3682 format->videoInfo.TransferFunction = transfer_function;
3683 format->videoInfo.ColorPrimaries = MFVideoPrimaries_BT709;
3684 format->videoInfo.SourceLighting = MFVideoLighting_office;
3685 format->videoInfo.FramesPerSecond.Numerator = 60;
3686 format->videoInfo.FramesPerSecond.Denominator = 1;
3687 format->videoInfo.NominalRange = MFNominalRange_Normal;
3688 format->videoInfo.GeometricAperture.Area.cx = width;
3689 format->videoInfo.GeometricAperture.Area.cy = height;
3690 format->videoInfo.MinimumDisplayAperture = format->videoInfo.GeometricAperture;
3691 memcpy(&format->guidFormat, &MFVideoFormat_Base, sizeof(format->guidFormat));
3692 format->guidFormat.Data1 = d3dformat;
3693 format->surfaceInfo.Format = d3dformat;
3695 return S_OK;
3698 static HRESULT mf_get_stride_for_bitmap_info_header(DWORD fourcc, const BITMAPINFOHEADER *bih, LONG *stride)
3700 HRESULT hr;
3702 if (FAILED(hr = MFGetStrideForBitmapInfoHeader(fourcc, bih->biWidth, stride))) return hr;
3703 if (bih->biHeight < 0) *stride *= -1;
3705 return hr;
3708 static const GUID * get_mf_subtype_for_am_subtype(const GUID *subtype)
3710 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB1))
3711 return &MFVideoFormat_RGB1;
3712 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB4))
3713 return &MFVideoFormat_RGB4;
3714 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8))
3715 return &MFVideoFormat_RGB8;
3716 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555))
3717 return &MFVideoFormat_RGB555;
3718 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565))
3719 return &MFVideoFormat_RGB565;
3720 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24))
3721 return &MFVideoFormat_RGB24;
3722 if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32))
3723 return &MFVideoFormat_RGB32;
3724 if (IsEqualGUID(subtype, &MEDIASUBTYPE_ARGB1555))
3725 return &MFVideoFormat_ARGB1555;
3726 if (IsEqualGUID(subtype, &MEDIASUBTYPE_ARGB4444))
3727 return &MFVideoFormat_ARGB4444;
3728 if (IsEqualGUID(subtype, &MEDIASUBTYPE_ARGB32))
3729 return &MFVideoFormat_ARGB32;
3730 if (IsEqualGUID(subtype, &MEDIASUBTYPE_A2R10G10B10))
3731 return &MFVideoFormat_A2B10G10R10;
3732 if (IsEqualGUID(subtype, &MEDIASUBTYPE_A2B10G10R10))
3733 return &MFVideoFormat_A2R10G10B10;
3734 return subtype;
3737 /***********************************************************************
3738 * MFCreateVideoMediaTypeFromVideoInfoHeader (mfplat.@)
3740 HRESULT WINAPI MFCreateVideoMediaTypeFromVideoInfoHeader(const KS_VIDEOINFOHEADER *vih, DWORD size, DWORD pixel_aspect_ratio_x,
3741 DWORD pixel_aspect_ratio_y, MFVideoInterlaceMode interlace_mode, QWORD video_flags, const GUID *subtype,
3742 IMFVideoMediaType **ret)
3744 FIXME("%p, %lu, %lu, %lu, %d, %I64x, %s, %p.\n", vih, size, pixel_aspect_ratio_x, pixel_aspect_ratio_y, interlace_mode,
3745 video_flags, debugstr_guid(subtype), ret);
3747 return E_NOTIMPL;
3750 /***********************************************************************
3751 * MFInitMediaTypeFromVideoInfoHeader2 (mfplat.@)
3753 HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader2(IMFMediaType *media_type, const VIDEOINFOHEADER2 *vih, UINT32 size,
3754 const GUID *subtype)
3756 HRESULT hr = S_OK;
3757 DWORD height;
3758 LONG stride;
3760 TRACE("%p, %p, %u, %s.\n", media_type, vih, size, debugstr_guid(subtype));
3762 IMFMediaType_DeleteAllItems(media_type);
3764 if (!subtype)
3766 switch (vih->bmiHeader.biBitCount)
3768 case 1: subtype = &MFVideoFormat_RGB1; break;
3769 case 4: subtype = &MFVideoFormat_RGB4; break;
3770 case 8: subtype = &MFVideoFormat_RGB8; break;
3771 case 16: subtype = &MFVideoFormat_RGB555; break;
3772 case 24: subtype = &MFVideoFormat_RGB24; break;
3773 case 32: subtype = &MFVideoFormat_RGB32; break;
3774 default: return E_INVALIDARG;
3778 height = abs(vih->bmiHeader.biHeight);
3780 mediatype_set_guid(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video, &hr);
3781 mediatype_set_guid(media_type, &MF_MT_SUBTYPE, subtype, &hr);
3782 mediatype_set_uint64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, 1, 1, &hr);
3783 mediatype_set_uint32(media_type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive, &hr);
3784 mediatype_set_uint64(media_type, &MF_MT_FRAME_SIZE, vih->bmiHeader.biWidth, height, &hr);
3786 if (SUCCEEDED(mf_get_stride_for_bitmap_info_header(subtype->Data1, &vih->bmiHeader, &stride)))
3788 mediatype_set_uint32(media_type, &MF_MT_DEFAULT_STRIDE, stride, &hr);
3789 mediatype_set_uint32(media_type, &MF_MT_SAMPLE_SIZE, abs(stride) * height, &hr);
3790 mediatype_set_uint32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1, &hr);
3791 mediatype_set_uint32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr);
3794 if (vih->bmiHeader.biSizeImage)
3795 mediatype_set_uint32(media_type, &MF_MT_SAMPLE_SIZE, vih->bmiHeader.biSizeImage, &hr);
3797 if (vih->rcSource.left || vih->rcSource.top || vih->rcSource.right || vih->rcSource.bottom)
3799 MFVideoArea aperture = {{0}};
3801 aperture.OffsetX.value = vih->rcSource.left;
3802 aperture.OffsetY.value = vih->rcSource.top;
3803 aperture.Area.cx = vih->rcSource.right - vih->rcSource.left;
3804 aperture.Area.cy = vih->rcSource.bottom - vih->rcSource.top;
3806 mediatype_set_uint32(media_type, &MF_MT_PAN_SCAN_ENABLED, 1, &hr);
3807 mediatype_set_blob(media_type, &MF_MT_PAN_SCAN_APERTURE, (BYTE *)&aperture, sizeof(aperture), &hr);
3808 mediatype_set_blob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture), &hr);
3811 if (SUCCEEDED(hr) && vih->AvgTimePerFrame)
3813 UINT32 num, den;
3814 if (SUCCEEDED(hr = MFAverageTimePerFrameToFrameRate(vih->AvgTimePerFrame, &num, &den)))
3815 mediatype_set_uint64(media_type, &MF_MT_FRAME_RATE, num, den, &hr);
3818 return hr;
3821 /***********************************************************************
3822 * MFInitMediaTypeFromVideoInfoHeader (mfplat.@)
3824 HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, const VIDEOINFOHEADER *vih, UINT32 size,
3825 const GUID *subtype)
3827 VIDEOINFOHEADER2 vih2 =
3829 .rcSource = vih->rcSource,
3830 .rcTarget = vih->rcTarget,
3831 .dwBitRate = vih->dwBitRate,
3832 .dwBitErrorRate = vih->dwBitErrorRate,
3833 .AvgTimePerFrame = vih->AvgTimePerFrame,
3834 .bmiHeader = vih->bmiHeader,
3837 TRACE("%p, %p, %u, %s.\n", media_type, vih, size, debugstr_guid(subtype));
3839 return MFInitMediaTypeFromVideoInfoHeader2(media_type, &vih2, sizeof(vih2), subtype);
3842 static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, UINT32 user_size, IMFMediaType *media_type)
3844 UINT32 num_channels, value;
3845 HRESULT hr;
3847 if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo)
3848 || IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2)
3849 || IsEqualGUID(&am_type->formattype, &FORMAT_MFVideoFormat))
3850 return E_INVALIDARG;
3852 if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx)
3853 || IsEqualGUID(&am_type->formattype, &GUID_NULL))
3855 WAVEFORMATEX *format;
3857 if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, &num_channels)))
3858 num_channels = 0;
3860 if (SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_CHANNEL_MASK, NULL))
3861 || SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, NULL))
3862 || SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, NULL))
3863 || num_channels > 2)
3865 WAVEFORMATEXTENSIBLE *format_ext;
3867 am_type->cbFormat = sizeof(*format_ext) + user_size;
3868 if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat)))
3869 return E_OUTOFMEMORY;
3870 format_ext = (WAVEFORMATEXTENSIBLE *)am_type->pbFormat;
3871 memset(format_ext, 0, sizeof(*format_ext));
3873 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, &value)))
3874 format_ext->dwChannelMask = value;
3875 else if (num_channels < ARRAY_SIZE(default_channel_mask))
3876 format_ext->dwChannelMask = default_channel_mask[num_channels];
3878 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value)))
3879 format_ext->Samples.wValidBitsPerSample = value;
3880 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, &value)))
3881 format_ext->Samples.wSamplesPerBlock = value;
3882 format_ext->SubFormat = am_type->subtype;
3884 format = &format_ext->Format;
3885 format->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3886 format->cbSize = sizeof(*format_ext) - sizeof(*format) + user_size;
3888 if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA,
3889 (BYTE *)(format_ext + 1), user_size, NULL)))
3890 return hr;
3892 else
3894 am_type->cbFormat = sizeof(*format) + user_size;
3895 if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat)))
3896 return E_OUTOFMEMORY;
3897 format = (WAVEFORMATEX *)am_type->pbFormat;
3898 memset(format, 0, sizeof(*format));
3900 format->wFormatTag = am_type->subtype.Data1;
3901 format->cbSize = user_size;
3903 if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA,
3904 (BYTE *)(format + 1), user_size, NULL)))
3905 return hr;
3908 format->nChannels = num_channels;
3909 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value)))
3910 format->nSamplesPerSec = value;
3911 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value)))
3912 format->nAvgBytesPerSec = value;
3913 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value)))
3914 format->nBlockAlign = value;
3915 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value)))
3916 format->wBitsPerSample = value;
3918 am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype);
3919 am_type->formattype = FORMAT_WaveFormatEx;
3921 else
3923 WARN("Unknown format %s\n", debugstr_mf_guid(&am_type->formattype));
3924 am_type->formattype = GUID_NULL;
3927 return S_OK;
3930 static void init_video_info_header2(VIDEOINFOHEADER2 *vih, const GUID *subtype, IMFMediaType *media_type)
3932 struct uncompressed_video_format *video_format = mf_get_video_format(subtype);
3933 UINT32 image_size, bitrate, sample_size, width, height;
3934 UINT64 frame_size, frame_rate;
3936 vih->bmiHeader.biSize = sizeof(vih->bmiHeader);
3937 vih->bmiHeader.biPlanes = 1;
3938 vih->bmiHeader.biBitCount = video_format ? video_format->bpp : 0;
3940 if (video_format && video_format->compression != -1)
3941 vih->bmiHeader.biCompression = video_format->compression;
3942 else
3943 vih->bmiHeader.biCompression = subtype->Data1;
3945 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BITRATE, &bitrate)))
3946 vih->dwBitRate = bitrate;
3947 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, &bitrate)))
3948 vih->dwBitErrorRate = bitrate;
3949 if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &frame_rate)) && (frame_rate >> 32))
3950 vih->AvgTimePerFrame = round(10000000. * (UINT32)frame_rate / (frame_rate >> 32));
3951 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &sample_size)))
3952 vih->bmiHeader.biSizeImage = sample_size;
3954 if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size)))
3956 BOOL bottom_up = vih->bmiHeader.biCompression == BI_RGB || vih->bmiHeader.biCompression == BI_BITFIELDS;
3957 INT32 stride;
3959 width = frame_size >> 32;
3960 if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, (UINT32 *)&stride)))
3961 stride = width * (bottom_up ? -1 : 1);
3962 else if (video_format)
3963 stride /= video_format->bpp / 8;
3964 height = (UINT32)frame_size;
3966 vih->bmiHeader.biWidth = abs(stride);
3967 vih->bmiHeader.biHeight = height * (bottom_up && stride >= 0 ? -1 : 1);
3969 if (SUCCEEDED(MFCalculateImageSize(subtype, abs(stride), height, &image_size)))
3970 vih->bmiHeader.biSizeImage = image_size;
3972 if (vih->bmiHeader.biWidth > width)
3974 vih->rcSource.right = vih->rcTarget.right = width;
3975 vih->rcSource.bottom = vih->rcTarget.bottom = height;
3980 static HRESULT init_am_media_type_video_format(AM_MEDIA_TYPE *am_type, UINT32 user_size, IMFMediaType *media_type)
3982 HRESULT hr;
3984 if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx))
3985 return E_INVALIDARG;
3987 if (IsEqualGUID(&am_type->formattype, &FORMAT_MFVideoFormat))
3988 return MFCreateMFVideoFormatFromMFMediaType(media_type, (MFVIDEOFORMAT **)&am_type->pbFormat,
3989 (UINT32 *)&am_type->cbFormat);
3991 if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo)
3992 || IsEqualGUID(&am_type->formattype, &GUID_NULL))
3994 VIDEOINFOHEADER2 vih = {{0}};
3995 VIDEOINFOHEADER *format;
3997 am_type->cbFormat = sizeof(*format) + user_size;
3998 if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat)))
3999 return E_OUTOFMEMORY;
4000 format = (VIDEOINFOHEADER *)am_type->pbFormat;
4001 memset(format, 0, sizeof(*format));
4003 init_video_info_header2(&vih, &am_type->subtype, media_type);
4004 format->rcSource = vih.rcSource;
4005 format->rcTarget = vih.rcTarget;
4006 format->dwBitRate = vih.dwBitRate;
4007 format->dwBitErrorRate = vih.dwBitErrorRate;
4008 format->AvgTimePerFrame = vih.AvgTimePerFrame;
4009 format->bmiHeader = vih.bmiHeader;
4011 if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA,
4012 (BYTE *)(format + 1), user_size, NULL)))
4013 return hr;
4014 format->bmiHeader.biSize += user_size;
4016 am_type->formattype = FORMAT_VideoInfo;
4017 am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype);
4019 else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2))
4021 VIDEOINFOHEADER2 *format;
4023 am_type->cbFormat = sizeof(*format) + user_size;
4024 if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat)))
4025 return E_OUTOFMEMORY;
4026 format = (VIDEOINFOHEADER2 *)am_type->pbFormat;
4027 memset(format, 0, sizeof(*format));
4029 init_video_info_header2(format, &am_type->subtype, media_type);
4031 if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA,
4032 (BYTE *)(format + 1), user_size, NULL)))
4033 return hr;
4034 format->bmiHeader.biSize += user_size;
4036 am_type->formattype = FORMAT_VideoInfo2;
4037 am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype);
4039 else
4041 WARN("Unknown format %s\n", debugstr_mf_guid(&am_type->formattype));
4042 am_type->formattype = GUID_NULL;
4045 return S_OK;
4048 /***********************************************************************
4049 * MFInitAMMediaTypeFromMFMediaType (mfplat.@)
4051 HRESULT WINAPI MFInitAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE *am_type)
4053 UINT32 value, user_size;
4054 HRESULT hr;
4056 TRACE("%p, %s, %p.\n", media_type, debugstr_mf_guid(&format), am_type);
4058 memset(am_type, 0, sizeof(*am_type));
4059 am_type->formattype = format;
4061 if (FAILED(hr = IMFMediaType_GetMajorType(media_type, &am_type->majortype))
4062 || FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &am_type->subtype)))
4063 goto done;
4065 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value)))
4066 am_type->bFixedSizeSamples = value;
4067 if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value)))
4068 am_type->lSampleSize = value;
4070 if (FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, NULL, 0, &user_size))
4071 && hr != E_NOT_SUFFICIENT_BUFFER)
4072 user_size = 0;
4074 if (IsEqualGUID(&am_type->majortype, &MFMediaType_Audio))
4075 hr = init_am_media_type_audio_format(am_type, user_size, media_type);
4076 else if (IsEqualGUID(&am_type->majortype, &MFMediaType_Video))
4077 hr = init_am_media_type_video_format(am_type, user_size, media_type);
4078 else
4080 FIXME("Not implemented!\n");
4081 hr = E_NOTIMPL;
4084 done:
4085 if (FAILED(hr))
4087 CoTaskMemFree(am_type->pbFormat);
4088 am_type->pbFormat = NULL;
4089 am_type->cbFormat = 0;
4092 return hr;
4095 /***********************************************************************
4096 * MFInitMediaTypeFromAMMediaType (mfplat.@)
4098 HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM_MEDIA_TYPE *am_type)
4100 HRESULT hr = S_OK;
4102 TRACE("%p, %p.\n", media_type, am_type);
4104 IMFMediaType_DeleteAllItems(media_type);
4106 if (IsEqualGUID(&am_type->majortype, &MEDIATYPE_Video))
4108 const GUID *subtype = get_mf_subtype_for_am_subtype(&am_type->subtype);
4110 if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo))
4111 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, (VIDEOINFOHEADER *)am_type->pbFormat, am_type->cbFormat, subtype);
4112 else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2))
4113 hr = MFInitMediaTypeFromVideoInfoHeader2(media_type, (VIDEOINFOHEADER2 *)am_type->pbFormat, am_type->cbFormat, subtype);
4114 else
4116 FIXME("Unsupported format type %s.\n", debugstr_guid(&am_type->formattype));
4117 return E_NOTIMPL;
4120 if (!am_type->bTemporalCompression && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL)))
4121 mediatype_set_uint32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr);
4122 if (am_type->bFixedSizeSamples && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL)))
4123 mediatype_set_uint32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1, &hr);
4124 if (am_type->lSampleSize && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL)))
4125 mediatype_set_uint32(media_type, &MF_MT_SAMPLE_SIZE, am_type->lSampleSize, &hr);
4127 else
4129 FIXME("Unsupported major type %s.\n", debugstr_guid(&am_type->majortype));
4130 return E_NOTIMPL;
4133 return hr;