include: Use known variables names in SYSTEM_INTERRUPT_INFORMATION.
[wine.git] / dlls / winegstreamer / mfplat.c
blob93f4b8d5bd78ceaa8dc2164cc8df632bd4d9abdf
1 /*
2 * Copyright 2019 Nikolay Sivov for CodeWeavers
3 * Copyright 2020 Zebediah Figura for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "gst_private.h"
22 #include "mfapi.h"
23 #include "ks.h"
24 #include "ksmedia.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
30 struct video_processor
32 IMFTransform IMFTransform_iface;
33 LONG refcount;
34 IMFAttributes *attributes;
35 IMFAttributes *output_attributes;
38 static struct video_processor *impl_video_processor_from_IMFTransform(IMFTransform *iface)
40 return CONTAINING_RECORD(iface, struct video_processor, IMFTransform_iface);
43 static HRESULT WINAPI video_processor_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
45 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
47 if (IsEqualIID(riid, &IID_IMFTransform) ||
48 IsEqualIID(riid, &IID_IUnknown))
50 *obj = iface;
51 IMFTransform_AddRef(iface);
52 return S_OK;
55 WARN("Unsupported %s.\n", debugstr_guid(riid));
56 *obj = NULL;
57 return E_NOINTERFACE;
60 static ULONG WINAPI video_processor_AddRef(IMFTransform *iface)
62 struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
63 ULONG refcount = InterlockedIncrement(&transform->refcount);
65 TRACE("%p, refcount %u.\n", iface, refcount);
67 return refcount;
70 static ULONG WINAPI video_processor_Release(IMFTransform *iface)
72 struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
73 ULONG refcount = InterlockedDecrement(&transform->refcount);
75 TRACE("%p, refcount %u.\n", iface, refcount);
77 if (!refcount)
79 if (transform->attributes)
80 IMFAttributes_Release(transform->attributes);
81 if (transform->output_attributes)
82 IMFAttributes_Release(transform->output_attributes);
83 free(transform);
86 return refcount;
89 static HRESULT WINAPI video_processor_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
90 DWORD *output_minimum, DWORD *output_maximum)
92 TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
94 *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
96 return S_OK;
99 static HRESULT WINAPI video_processor_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
101 TRACE("%p, %p, %p.\n", iface, inputs, outputs);
103 *inputs = *outputs = 1;
105 return S_OK;
108 static HRESULT WINAPI video_processor_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
109 DWORD output_size, DWORD *outputs)
111 return E_NOTIMPL;
114 static HRESULT WINAPI video_processor_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
116 return E_NOTIMPL;
119 static HRESULT WINAPI video_processor_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
121 return E_NOTIMPL;
124 static HRESULT WINAPI video_processor_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
126 struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
128 TRACE("%p, %p.\n", iface, attributes);
130 *attributes = transform->attributes;
131 IMFAttributes_AddRef(*attributes);
133 return S_OK;
136 static HRESULT WINAPI video_processor_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
137 IMFAttributes **attributes)
139 return E_NOTIMPL;
142 static HRESULT WINAPI video_processor_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
143 IMFAttributes **attributes)
145 struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
147 TRACE("%p, %u, %p.\n", iface, id, attributes);
149 *attributes = transform->output_attributes;
150 IMFAttributes_AddRef(*attributes);
152 return S_OK;
155 static HRESULT WINAPI video_processor_DeleteInputStream(IMFTransform *iface, DWORD id)
157 TRACE("%p, %u.\n", iface, id);
159 return E_NOTIMPL;
162 static HRESULT WINAPI video_processor_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
164 TRACE("%p, %u, %p.\n", iface, streams, ids);
166 return E_NOTIMPL;
169 static HRESULT WINAPI video_processor_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
170 IMFMediaType **type)
172 FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
174 return E_NOTIMPL;
177 static HRESULT WINAPI video_processor_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
178 IMFMediaType **type)
180 FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
182 return E_NOTIMPL;
185 static HRESULT WINAPI video_processor_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
187 FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
189 return E_NOTIMPL;
192 static HRESULT WINAPI video_processor_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
194 FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
196 return E_NOTIMPL;
199 static HRESULT WINAPI video_processor_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
201 FIXME("%p, %u, %p.\n", iface, id, type);
203 return E_NOTIMPL;
206 static HRESULT WINAPI video_processor_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
208 FIXME("%p, %u, %p.\n", iface, id, type);
210 return E_NOTIMPL;
213 static HRESULT WINAPI video_processor_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
215 FIXME("%p, %u, %p.\n", iface, id, flags);
217 return E_NOTIMPL;
220 static HRESULT WINAPI video_processor_GetOutputStatus(IMFTransform *iface, DWORD *flags)
222 FIXME("%p, %p.\n", iface, flags);
224 return E_NOTIMPL;
227 static HRESULT WINAPI video_processor_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
229 FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
231 return E_NOTIMPL;
234 static HRESULT WINAPI video_processor_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
236 TRACE("%p, %u, %p.\n", iface, id, event);
238 return E_NOTIMPL;
241 static HRESULT WINAPI video_processor_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
243 FIXME("%p, %u.\n", iface, message);
245 return E_NOTIMPL;
248 static HRESULT WINAPI video_processor_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
250 FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
252 return E_NOTIMPL;
255 static HRESULT WINAPI video_processor_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
256 MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
258 FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
260 return E_NOTIMPL;
263 static const IMFTransformVtbl video_processor_vtbl =
265 video_processor_QueryInterface,
266 video_processor_AddRef,
267 video_processor_Release,
268 video_processor_GetStreamLimits,
269 video_processor_GetStreamCount,
270 video_processor_GetStreamIDs,
271 video_processor_GetInputStreamInfo,
272 video_processor_GetOutputStreamInfo,
273 video_processor_GetAttributes,
274 video_processor_GetInputStreamAttributes,
275 video_processor_GetOutputStreamAttributes,
276 video_processor_DeleteInputStream,
277 video_processor_AddInputStreams,
278 video_processor_GetInputAvailableType,
279 video_processor_GetOutputAvailableType,
280 video_processor_SetInputType,
281 video_processor_SetOutputType,
282 video_processor_GetInputCurrentType,
283 video_processor_GetOutputCurrentType,
284 video_processor_GetInputStatus,
285 video_processor_GetOutputStatus,
286 video_processor_SetOutputBounds,
287 video_processor_ProcessEvent,
288 video_processor_ProcessMessage,
289 video_processor_ProcessInput,
290 video_processor_ProcessOutput,
293 struct class_factory
295 IClassFactory IClassFactory_iface;
296 LONG refcount;
297 HRESULT (*create_instance)(REFIID riid, void **obj);
300 static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
302 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
305 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
307 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
309 if (IsEqualGUID(riid, &IID_IClassFactory) ||
310 IsEqualGUID(riid, &IID_IUnknown))
312 *obj = iface;
313 IClassFactory_AddRef(iface);
314 return S_OK;
317 WARN("%s is not supported.\n", debugstr_guid(riid));
318 *obj = NULL;
319 return E_NOINTERFACE;
322 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
324 struct class_factory *factory = impl_from_IClassFactory(iface);
325 return InterlockedIncrement(&factory->refcount);
328 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
330 struct class_factory *factory = impl_from_IClassFactory(iface);
331 ULONG refcount = InterlockedDecrement(&factory->refcount);
333 if (!refcount)
334 free(factory);
336 return refcount;
339 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
341 struct class_factory *factory = impl_from_IClassFactory(iface);
343 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), obj);
345 if (outer)
347 *obj = NULL;
348 return CLASS_E_NOAGGREGATION;
351 return factory->create_instance(riid, obj);
354 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock)
356 TRACE("%p, %d.\n", iface, dolock);
357 return S_OK;
360 static const IClassFactoryVtbl class_factory_vtbl =
362 class_factory_QueryInterface,
363 class_factory_AddRef,
364 class_factory_Release,
365 class_factory_CreateInstance,
366 class_factory_LockServer,
369 static HRESULT video_processor_create(REFIID riid, void **ret)
371 struct video_processor *object;
372 HRESULT hr;
374 if (!(object = calloc(1, sizeof(*object))))
375 return E_OUTOFMEMORY;
377 object->IMFTransform_iface.lpVtbl = &video_processor_vtbl;
378 object->refcount = 1;
380 if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
381 goto failed;
383 if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
384 goto failed;
386 *ret = &object->IMFTransform_iface;
387 return S_OK;
389 failed:
391 IMFTransform_Release(&object->IMFTransform_iface);
392 return hr;
395 static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
397 static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
399 static const struct class_object
401 const GUID *clsid;
402 HRESULT (*create_instance)(REFIID riid, void **obj);
404 class_objects[] =
406 { &CLSID_VideoProcessorMFT, &video_processor_create },
407 { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
408 { &CLSID_WINEAudioConverter, &audio_converter_create },
411 HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
413 struct class_factory *factory;
414 unsigned int i;
415 HRESULT hr;
417 for (i = 0; i < ARRAY_SIZE(class_objects); ++i)
419 if (IsEqualGUID(class_objects[i].clsid, rclsid))
421 if (!(factory = malloc(sizeof(*factory))))
422 return E_OUTOFMEMORY;
424 factory->IClassFactory_iface.lpVtbl = &class_factory_vtbl;
425 factory->refcount = 1;
426 factory->create_instance = class_objects[i].create_instance;
428 hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
429 IClassFactory_Release(&factory->IClassFactory_iface);
430 return hr;
434 return CLASS_E_CLASSNOTAVAILABLE;
437 static WCHAR audio_converterW[] = L"Audio Converter";
438 static const GUID *audio_converter_supported_types[] =
440 &MFAudioFormat_PCM,
441 &MFAudioFormat_Float,
444 static const struct mft
446 const GUID *clsid;
447 const GUID *category;
448 LPWSTR name;
449 const UINT32 flags;
450 const GUID *major_type;
451 const UINT32 input_types_count;
452 const GUID **input_types;
453 const UINT32 output_types_count;
454 const GUID **output_types;
456 mfts[] =
459 &CLSID_WINEAudioConverter,
460 &MFT_CATEGORY_AUDIO_EFFECT,
461 audio_converterW,
462 MFT_ENUM_FLAG_SYNCMFT,
463 &MFMediaType_Audio,
464 ARRAY_SIZE(audio_converter_supported_types),
465 audio_converter_supported_types,
466 ARRAY_SIZE(audio_converter_supported_types),
467 audio_converter_supported_types,
471 HRESULT mfplat_DllRegisterServer(void)
473 unsigned int i, j;
474 HRESULT hr;
475 MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
477 for (i = 0; i < ARRAY_SIZE(mfts); i++)
479 const struct mft *cur = &mfts[i];
481 for (j = 0; j < cur->input_types_count; j++)
483 input_types[j].guidMajorType = *(cur->major_type);
484 input_types[j].guidSubtype = *(cur->input_types[j]);
486 for (j = 0; j < cur->output_types_count; j++)
488 output_types[j].guidMajorType = *(cur->major_type);
489 output_types[j].guidSubtype = *(cur->output_types[j]);
492 hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count,
493 input_types, cur->output_types_count, output_types, NULL);
495 if (FAILED(hr))
497 FIXME("Failed to register MFT, hr %#x\n", hr);
498 return hr;
501 return S_OK;
504 static const struct
506 const GUID *subtype;
507 enum wg_video_format format;
509 video_formats[] =
511 {&MFVideoFormat_ARGB32, WG_VIDEO_FORMAT_BGRA},
512 {&MFVideoFormat_RGB32, WG_VIDEO_FORMAT_BGRx},
513 {&MFVideoFormat_RGB24, WG_VIDEO_FORMAT_BGR},
514 {&MFVideoFormat_RGB555, WG_VIDEO_FORMAT_RGB15},
515 {&MFVideoFormat_RGB565, WG_VIDEO_FORMAT_RGB16},
516 {&MFVideoFormat_AYUV, WG_VIDEO_FORMAT_AYUV},
517 {&MFVideoFormat_I420, WG_VIDEO_FORMAT_I420},
518 {&MFVideoFormat_IYUV, WG_VIDEO_FORMAT_I420},
519 {&MFVideoFormat_NV12, WG_VIDEO_FORMAT_NV12},
520 {&MFVideoFormat_UYVY, WG_VIDEO_FORMAT_UYVY},
521 {&MFVideoFormat_YUY2, WG_VIDEO_FORMAT_YUY2},
522 {&MFVideoFormat_YV12, WG_VIDEO_FORMAT_YV12},
523 {&MFVideoFormat_YVYU, WG_VIDEO_FORMAT_YVYU},
526 static const struct
528 const GUID *subtype;
529 UINT32 depth;
530 enum wg_audio_format format;
532 audio_formats[] =
534 {&MFAudioFormat_PCM, 8, WG_AUDIO_FORMAT_U8},
535 {&MFAudioFormat_PCM, 16, WG_AUDIO_FORMAT_S16LE},
536 {&MFAudioFormat_PCM, 24, WG_AUDIO_FORMAT_S24LE},
537 {&MFAudioFormat_PCM, 32, WG_AUDIO_FORMAT_S32LE},
538 {&MFAudioFormat_Float, 32, WG_AUDIO_FORMAT_F32LE},
539 {&MFAudioFormat_Float, 64, WG_AUDIO_FORMAT_F64LE},
542 static inline UINT64 make_uint64(UINT32 high, UINT32 low)
544 return ((UINT64)high << 32) | low;
547 static IMFMediaType *mf_media_type_from_wg_format_audio(const struct wg_format *format)
549 IMFMediaType *type;
550 unsigned int i;
552 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
554 if (format->u.audio.format == audio_formats[i].format)
556 if (FAILED(MFCreateMediaType(&type)))
557 return NULL;
559 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
560 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, audio_formats[i].subtype);
561 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, audio_formats[i].depth);
562 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->u.audio.rate);
563 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, format->u.audio.channels);
564 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, format->u.audio.channel_mask);
565 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
567 return type;
571 return NULL;
574 static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format *format)
576 IMFMediaType *type;
577 unsigned int i;
579 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
581 if (format->u.video.format == video_formats[i].format)
583 if (FAILED(MFCreateMediaType(&type)))
584 return NULL;
586 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
587 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, video_formats[i].subtype);
588 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE,
589 make_uint64(format->u.video.width, format->u.video.height));
590 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_RATE,
591 make_uint64(format->u.video.fps_n, format->u.video.fps_d));
592 IMFMediaType_SetUINT32(type, &MF_MT_COMPRESSED, FALSE);
593 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
594 IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
596 return type;
600 return NULL;
603 IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
605 switch (format->major_type)
607 case WG_MAJOR_TYPE_UNKNOWN:
608 return NULL;
610 case WG_MAJOR_TYPE_AUDIO:
611 return mf_media_type_from_wg_format_audio(format);
613 case WG_MAJOR_TYPE_VIDEO:
614 return mf_media_type_from_wg_format_video(format);
617 assert(0);
618 return NULL;
621 static void mf_media_type_to_wg_format_audio(IMFMediaType *type, struct wg_format *format)
623 UINT32 rate, channels, channel_mask, depth;
624 unsigned int i;
625 GUID subtype;
627 if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
629 FIXME("Subtype is not set.\n");
630 return;
632 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
634 FIXME("Sample rate is not set.\n");
635 return;
637 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
639 FIXME("Channel count is not set.\n");
640 return;
642 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
644 FIXME("Depth is not set.\n");
645 return;
647 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask)))
649 if (channels == 1)
650 channel_mask = KSAUDIO_SPEAKER_MONO;
651 else if (channels == 2)
652 channel_mask = KSAUDIO_SPEAKER_STEREO;
653 else
655 FIXME("Channel mask is not set.\n");
656 return;
660 format->major_type = WG_MAJOR_TYPE_AUDIO;
661 format->u.audio.channels = channels;
662 format->u.audio.channel_mask = channel_mask;
663 format->u.audio.rate = rate;
665 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
667 if (IsEqualGUID(&subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth)
669 format->u.audio.format = audio_formats[i].format;
670 return;
673 FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(&subtype), depth);
676 static void mf_media_type_to_wg_format_video(IMFMediaType *type, struct wg_format *format)
678 UINT64 frame_rate, frame_size;
679 unsigned int i;
680 GUID subtype;
682 if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
684 FIXME("Subtype is not set.\n");
685 return;
687 if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
689 FIXME("Frame size is not set.\n");
690 return;
693 format->major_type = WG_MAJOR_TYPE_VIDEO;
694 format->u.video.width = (UINT32)(frame_size >> 32);
695 format->u.video.height = (UINT32)frame_size;
696 format->u.video.fps_n = 1;
697 format->u.video.fps_d = 1;
699 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
701 format->u.video.fps_n = (UINT32)(frame_rate >> 32);
702 format->u.video.fps_d = (UINT32)frame_rate;
705 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
707 if (IsEqualGUID(&subtype, video_formats[i].subtype))
709 format->u.video.format = video_formats[i].format;
710 return;
713 FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype));
716 void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
718 GUID major_type;
720 memset(format, 0, sizeof(*format));
722 if (FAILED(IMFMediaType_GetMajorType(type, &major_type)))
724 FIXME("Major type is not set.\n");
725 return;
728 if (IsEqualGUID(&major_type, &MFMediaType_Audio))
729 mf_media_type_to_wg_format_audio(type, format);
730 else if (IsEqualGUID(&major_type, &MFMediaType_Video))
731 mf_media_type_to_wg_format_video(type, format);
732 else
733 FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));