d3dx9: Unify calling parse_mesh helper functions.
[wine.git] / dlls / winegstreamer / mfplat.c
blob0e1d489d8e541722b4e29487f219a2e28aad4ca7
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 "ks.h"
23 #include "ksmedia.h"
24 #include "wmcodecdsp.h"
25 #include "initguid.h"
26 #include "d3d9types.h"
27 #include "mfapi.h"
29 #include "wine/debug.h"
30 #include "wine/list.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
34 DEFINE_GUID(DMOVideoFormat_RGB32,D3DFMT_X8R8G8B8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
35 DEFINE_GUID(DMOVideoFormat_RGB24,D3DFMT_R8G8B8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
36 DEFINE_GUID(DMOVideoFormat_RGB565,D3DFMT_R5G6B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
37 DEFINE_GUID(DMOVideoFormat_RGB555,D3DFMT_X1R5G5B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
38 DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
39 DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1);
40 DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S,MAKEFOURCC('V','C','1','S'));
41 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IV50,MAKEFOURCC('I','V','5','0'));
43 struct class_factory
45 IClassFactory IClassFactory_iface;
46 LONG refcount;
47 HRESULT (*create_instance)(REFIID riid, void **obj);
50 static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
52 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
55 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
57 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
59 if (IsEqualGUID(riid, &IID_IClassFactory) ||
60 IsEqualGUID(riid, &IID_IUnknown))
62 *obj = iface;
63 IClassFactory_AddRef(iface);
64 return S_OK;
67 WARN("%s is not supported.\n", debugstr_guid(riid));
68 *obj = NULL;
69 return E_NOINTERFACE;
72 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
74 struct class_factory *factory = impl_from_IClassFactory(iface);
75 return InterlockedIncrement(&factory->refcount);
78 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
80 struct class_factory *factory = impl_from_IClassFactory(iface);
81 ULONG refcount = InterlockedDecrement(&factory->refcount);
83 if (!refcount)
84 free(factory);
86 return refcount;
89 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
91 struct class_factory *factory = impl_from_IClassFactory(iface);
93 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), obj);
95 if (outer)
97 *obj = NULL;
98 return CLASS_E_NOAGGREGATION;
101 return factory->create_instance(riid, obj);
104 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock)
106 TRACE("%p, %d.\n", iface, dolock);
107 return S_OK;
110 static const IClassFactoryVtbl class_factory_vtbl =
112 class_factory_QueryInterface,
113 class_factory_AddRef,
114 class_factory_Release,
115 class_factory_CreateInstance,
116 class_factory_LockServer,
119 static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
121 static const struct class_object
123 const GUID *clsid;
124 HRESULT (*create_instance)(REFIID riid, void **obj);
126 class_objects[] =
128 { &CLSID_VideoProcessorMFT, &video_processor_create },
129 { &CLSID_GStreamerByteStreamHandler, &gstreamer_byte_stream_handler_create },
130 { &CLSID_MSAACDecMFT, &aac_decoder_create },
131 { &CLSID_MSH264DecoderMFT, &h264_decoder_create },
134 HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
136 struct class_factory *factory;
137 unsigned int i;
138 HRESULT hr;
140 for (i = 0; i < ARRAY_SIZE(class_objects); ++i)
142 if (IsEqualGUID(class_objects[i].clsid, rclsid))
144 if (!(factory = malloc(sizeof(*factory))))
145 return E_OUTOFMEMORY;
147 factory->IClassFactory_iface.lpVtbl = &class_factory_vtbl;
148 factory->refcount = 1;
149 factory->create_instance = class_objects[i].create_instance;
151 hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
152 IClassFactory_Release(&factory->IClassFactory_iface);
153 return hr;
157 return CLASS_E_CLASSNOTAVAILABLE;
160 HRESULT mfplat_DllRegisterServer(void)
162 MFT_REGISTER_TYPE_INFO resampler_types[] =
164 {MFMediaType_Audio, MFAudioFormat_PCM},
165 {MFMediaType_Audio, MFAudioFormat_Float},
168 MFT_REGISTER_TYPE_INFO aac_decoder_input_types[] =
170 {MFMediaType_Audio, MFAudioFormat_AAC},
171 {MFMediaType_Audio, MFAudioFormat_RAW_AAC},
172 {MFMediaType_Audio, MFAudioFormat_ADTS},
174 MFT_REGISTER_TYPE_INFO aac_decoder_output_types[] =
176 {MFMediaType_Audio, MFAudioFormat_Float},
177 {MFMediaType_Audio, MFAudioFormat_PCM},
180 MFT_REGISTER_TYPE_INFO wma_decoder_input_types[] =
182 {MFMediaType_Audio, MEDIASUBTYPE_MSAUDIO1},
183 {MFMediaType_Audio, MFAudioFormat_WMAudioV8},
184 {MFMediaType_Audio, MFAudioFormat_WMAudioV9},
185 {MFMediaType_Audio, MFAudioFormat_WMAudio_Lossless},
187 MFT_REGISTER_TYPE_INFO wma_decoder_output_types[] =
189 {MFMediaType_Audio, MFAudioFormat_PCM},
190 {MFMediaType_Audio, MFAudioFormat_Float},
193 MFT_REGISTER_TYPE_INFO h264_decoder_input_types[] =
195 {MFMediaType_Video, MFVideoFormat_H264},
196 {MFMediaType_Video, MFVideoFormat_H264_ES},
198 MFT_REGISTER_TYPE_INFO h264_decoder_output_types[] =
200 {MFMediaType_Video, MFVideoFormat_NV12},
201 {MFMediaType_Video, MFVideoFormat_YV12},
202 {MFMediaType_Video, MFVideoFormat_IYUV},
203 {MFMediaType_Video, MFVideoFormat_I420},
204 {MFMediaType_Video, MFVideoFormat_YUY2},
207 MFT_REGISTER_TYPE_INFO video_processor_input_types[] =
209 {MFMediaType_Video, MFVideoFormat_IYUV},
210 {MFMediaType_Video, MFVideoFormat_YV12},
211 {MFMediaType_Video, MFVideoFormat_NV12},
212 {MFMediaType_Video, MFVideoFormat_YUY2},
213 {MFMediaType_Video, MFVideoFormat_ARGB32},
214 {MFMediaType_Video, MFVideoFormat_RGB32},
215 {MFMediaType_Video, MFVideoFormat_NV11},
216 {MFMediaType_Video, MFVideoFormat_AYUV},
217 {MFMediaType_Video, MFVideoFormat_UYVY},
218 {MFMediaType_Video, MEDIASUBTYPE_P208},
219 {MFMediaType_Video, MFVideoFormat_RGB24},
220 {MFMediaType_Video, MFVideoFormat_RGB555},
221 {MFMediaType_Video, MFVideoFormat_RGB565},
222 {MFMediaType_Video, MFVideoFormat_RGB8},
223 {MFMediaType_Video, MFVideoFormat_I420},
224 {MFMediaType_Video, MFVideoFormat_Y216},
225 {MFMediaType_Video, MFVideoFormat_v410},
226 {MFMediaType_Video, MFVideoFormat_Y41P},
227 {MFMediaType_Video, MFVideoFormat_Y41T},
228 {MFMediaType_Video, MFVideoFormat_Y42T},
229 {MFMediaType_Video, MFVideoFormat_YVYU},
230 {MFMediaType_Video, MFVideoFormat_420O},
232 MFT_REGISTER_TYPE_INFO video_processor_output_types[] =
234 {MFMediaType_Video, MFVideoFormat_IYUV},
235 {MFMediaType_Video, MFVideoFormat_YV12},
236 {MFMediaType_Video, MFVideoFormat_NV12},
237 {MFMediaType_Video, MFVideoFormat_YUY2},
238 {MFMediaType_Video, MFVideoFormat_ARGB32},
239 {MFMediaType_Video, MFVideoFormat_RGB32},
240 {MFMediaType_Video, MFVideoFormat_NV11},
241 {MFMediaType_Video, MFVideoFormat_AYUV},
242 {MFMediaType_Video, MFVideoFormat_UYVY},
243 {MFMediaType_Video, MEDIASUBTYPE_P208},
244 {MFMediaType_Video, MFVideoFormat_RGB24},
245 {MFMediaType_Video, MFVideoFormat_RGB555},
246 {MFMediaType_Video, MFVideoFormat_RGB565},
247 {MFMediaType_Video, MFVideoFormat_RGB8},
248 {MFMediaType_Video, MFVideoFormat_I420},
249 {MFMediaType_Video, MFVideoFormat_Y216},
250 {MFMediaType_Video, MFVideoFormat_v410},
251 {MFMediaType_Video, MFVideoFormat_Y41P},
252 {MFMediaType_Video, MFVideoFormat_Y41T},
253 {MFMediaType_Video, MFVideoFormat_Y42T},
254 {MFMediaType_Video, MFVideoFormat_YVYU},
257 MFT_REGISTER_TYPE_INFO wmv_decoder_input_types[] =
259 {MFMediaType_Video, MFVideoFormat_WMV1},
260 {MFMediaType_Video, MFVideoFormat_WMV2},
261 {MFMediaType_Video, MFVideoFormat_WMV3},
262 {MFMediaType_Video, MEDIASUBTYPE_WMVP},
263 {MFMediaType_Video, MEDIASUBTYPE_WVP2},
264 {MFMediaType_Video, MEDIASUBTYPE_WMVR},
265 {MFMediaType_Video, MEDIASUBTYPE_WMVA},
266 {MFMediaType_Video, MFVideoFormat_WVC1},
267 {MFMediaType_Video, MFVideoFormat_VC1S},
269 MFT_REGISTER_TYPE_INFO wmv_decoder_output_types[] =
271 {MFMediaType_Video, MFVideoFormat_YV12},
272 {MFMediaType_Video, MFVideoFormat_YUY2},
273 {MFMediaType_Video, MFVideoFormat_UYVY},
274 {MFMediaType_Video, MFVideoFormat_YVYU},
275 {MFMediaType_Video, MFVideoFormat_NV11},
276 {MFMediaType_Video, MFVideoFormat_NV12},
277 {MFMediaType_Video, DMOVideoFormat_RGB32},
278 {MFMediaType_Video, DMOVideoFormat_RGB24},
279 {MFMediaType_Video, DMOVideoFormat_RGB565},
280 {MFMediaType_Video, DMOVideoFormat_RGB555},
281 {MFMediaType_Video, DMOVideoFormat_RGB8},
284 MFT_REGISTER_TYPE_INFO color_convert_input_types[] =
286 {MFMediaType_Video, MFVideoFormat_YV12},
287 {MFMediaType_Video, MFVideoFormat_YUY2},
288 {MFMediaType_Video, MFVideoFormat_UYVY},
289 {MFMediaType_Video, MFVideoFormat_AYUV},
290 {MFMediaType_Video, MFVideoFormat_NV12},
291 {MFMediaType_Video, DMOVideoFormat_RGB32},
292 {MFMediaType_Video, DMOVideoFormat_RGB565},
293 {MFMediaType_Video, MFVideoFormat_I420},
294 {MFMediaType_Video, MFVideoFormat_IYUV},
295 {MFMediaType_Video, MFVideoFormat_YVYU},
296 {MFMediaType_Video, DMOVideoFormat_RGB24},
297 {MFMediaType_Video, DMOVideoFormat_RGB555},
298 {MFMediaType_Video, DMOVideoFormat_RGB8},
299 {MFMediaType_Video, MEDIASUBTYPE_V216},
300 {MFMediaType_Video, MEDIASUBTYPE_V410},
301 {MFMediaType_Video, MFVideoFormat_NV11},
302 {MFMediaType_Video, MFVideoFormat_Y41P},
303 {MFMediaType_Video, MFVideoFormat_Y41T},
304 {MFMediaType_Video, MFVideoFormat_Y42T},
305 {MFMediaType_Video, MFVideoFormat_YVU9},
307 MFT_REGISTER_TYPE_INFO color_convert_output_types[] =
309 {MFMediaType_Video, MFVideoFormat_YV12},
310 {MFMediaType_Video, MFVideoFormat_YUY2},
311 {MFMediaType_Video, MFVideoFormat_UYVY},
312 {MFMediaType_Video, MFVideoFormat_AYUV},
313 {MFMediaType_Video, MFVideoFormat_NV12},
314 {MFMediaType_Video, DMOVideoFormat_RGB32},
315 {MFMediaType_Video, DMOVideoFormat_RGB565},
316 {MFMediaType_Video, MFVideoFormat_I420},
317 {MFMediaType_Video, MFVideoFormat_IYUV},
318 {MFMediaType_Video, MFVideoFormat_YVYU},
319 {MFMediaType_Video, DMOVideoFormat_RGB24},
320 {MFMediaType_Video, DMOVideoFormat_RGB555},
321 {MFMediaType_Video, DMOVideoFormat_RGB8},
322 {MFMediaType_Video, MEDIASUBTYPE_V216},
323 {MFMediaType_Video, MEDIASUBTYPE_V410},
324 {MFMediaType_Video, MFVideoFormat_NV11},
327 struct mft
329 GUID clsid;
330 GUID category;
331 WCHAR name[MAX_PATH];
332 UINT32 flags;
333 UINT32 input_types_count;
334 MFT_REGISTER_TYPE_INFO *input_types;
335 UINT32 output_types_count;
336 MFT_REGISTER_TYPE_INFO *output_types;
338 mfts[] =
341 CLSID_MSAACDecMFT,
342 MFT_CATEGORY_AUDIO_DECODER,
343 L"Microsoft AAC Audio Decoder MFT",
344 MFT_ENUM_FLAG_SYNCMFT,
345 ARRAY_SIZE(aac_decoder_input_types),
346 aac_decoder_input_types,
347 ARRAY_SIZE(aac_decoder_output_types),
348 aac_decoder_output_types,
351 CLSID_WMADecMediaObject,
352 MFT_CATEGORY_AUDIO_DECODER,
353 L"WMAudio Decoder MFT",
354 MFT_ENUM_FLAG_SYNCMFT,
355 ARRAY_SIZE(wma_decoder_input_types),
356 wma_decoder_input_types,
357 ARRAY_SIZE(wma_decoder_output_types),
358 wma_decoder_output_types,
361 CLSID_MSH264DecoderMFT,
362 MFT_CATEGORY_VIDEO_DECODER,
363 L"Microsoft H264 Video Decoder MFT",
364 MFT_ENUM_FLAG_SYNCMFT,
365 ARRAY_SIZE(h264_decoder_input_types),
366 h264_decoder_input_types,
367 ARRAY_SIZE(h264_decoder_output_types),
368 h264_decoder_output_types,
371 CLSID_WMVDecoderMFT,
372 MFT_CATEGORY_VIDEO_DECODER,
373 L"WMVideo Decoder MFT",
374 MFT_ENUM_FLAG_SYNCMFT,
375 ARRAY_SIZE(wmv_decoder_input_types),
376 wmv_decoder_input_types,
377 ARRAY_SIZE(wmv_decoder_output_types),
378 wmv_decoder_output_types,
381 CLSID_VideoProcessorMFT,
382 MFT_CATEGORY_VIDEO_PROCESSOR,
383 L"Microsoft Video Processor MFT",
384 MFT_ENUM_FLAG_SYNCMFT,
385 ARRAY_SIZE(video_processor_input_types),
386 video_processor_input_types,
387 ARRAY_SIZE(video_processor_output_types),
388 video_processor_output_types,
391 CLSID_CResamplerMediaObject,
392 MFT_CATEGORY_AUDIO_EFFECT,
393 L"Resampler MFT",
394 MFT_ENUM_FLAG_SYNCMFT,
395 ARRAY_SIZE(resampler_types),
396 resampler_types,
397 ARRAY_SIZE(resampler_types),
398 resampler_types,
401 CLSID_CColorConvertDMO,
402 MFT_CATEGORY_VIDEO_EFFECT,
403 L"Color Converter MFT",
404 MFT_ENUM_FLAG_SYNCMFT,
405 ARRAY_SIZE(color_convert_input_types),
406 color_convert_input_types,
407 ARRAY_SIZE(color_convert_output_types),
408 color_convert_output_types,
412 unsigned int i;
413 HRESULT hr;
415 for (i = 0; i < ARRAY_SIZE(mfts); i++)
417 hr = MFTRegister(mfts[i].clsid, mfts[i].category, mfts[i].name, mfts[i].flags, mfts[i].input_types_count,
418 mfts[i].input_types, mfts[i].output_types_count, mfts[i].output_types, NULL);
420 if (FAILED(hr))
422 FIXME("Failed to register MFT, hr %#lx.\n", hr);
423 return hr;
427 return S_OK;
430 static const struct
432 const GUID *subtype;
433 enum wg_video_format format;
435 video_formats[] =
437 {&MFVideoFormat_ARGB32, WG_VIDEO_FORMAT_BGRA},
438 {&MFVideoFormat_RGB32, WG_VIDEO_FORMAT_BGRx},
439 {&MFVideoFormat_RGB24, WG_VIDEO_FORMAT_BGR},
440 {&MFVideoFormat_RGB555, WG_VIDEO_FORMAT_RGB15},
441 {&MFVideoFormat_RGB565, WG_VIDEO_FORMAT_RGB16},
442 {&MFVideoFormat_AYUV, WG_VIDEO_FORMAT_AYUV},
443 {&MFVideoFormat_I420, WG_VIDEO_FORMAT_I420},
444 {&MFVideoFormat_IYUV, WG_VIDEO_FORMAT_I420},
445 {&MFVideoFormat_NV12, WG_VIDEO_FORMAT_NV12},
446 {&MFVideoFormat_UYVY, WG_VIDEO_FORMAT_UYVY},
447 {&MFVideoFormat_YUY2, WG_VIDEO_FORMAT_YUY2},
448 {&MFVideoFormat_YV12, WG_VIDEO_FORMAT_YV12},
449 {&MFVideoFormat_YVYU, WG_VIDEO_FORMAT_YVYU},
452 static const struct
454 const GUID *subtype;
455 UINT32 depth;
456 enum wg_audio_format format;
458 audio_formats[] =
460 {&MFAudioFormat_PCM, 8, WG_AUDIO_FORMAT_U8},
461 {&MFAudioFormat_PCM, 16, WG_AUDIO_FORMAT_S16LE},
462 {&MFAudioFormat_PCM, 24, WG_AUDIO_FORMAT_S24LE},
463 {&MFAudioFormat_PCM, 32, WG_AUDIO_FORMAT_S32LE},
464 {&MFAudioFormat_Float, 32, WG_AUDIO_FORMAT_F32LE},
465 {&MFAudioFormat_Float, 64, WG_AUDIO_FORMAT_F64LE},
468 static inline UINT64 make_uint64(UINT32 high, UINT32 low)
470 return ((UINT64)high << 32) | low;
473 static IMFMediaType *mf_media_type_from_wg_format_audio(const struct wg_format *format)
475 unsigned int i, block_align;
476 IMFMediaType *type;
478 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
480 if (format->u.audio.format == audio_formats[i].format)
482 if (FAILED(MFCreateMediaType(&type)))
483 return NULL;
485 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
486 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, audio_formats[i].subtype);
487 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, audio_formats[i].depth);
488 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->u.audio.rate);
489 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, format->u.audio.channels);
490 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, format->u.audio.channel_mask);
491 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
493 block_align = format->u.audio.channels * audio_formats[i].depth / 8;
494 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, block_align);
495 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, block_align * format->u.audio.rate);
497 return type;
501 FIXME("Unknown audio format %#x.\n", format->u.audio.format);
502 return NULL;
505 static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format *format)
507 IMFMediaType *type;
508 unsigned int i;
510 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
512 if (format->u.video.format == video_formats[i].format)
514 unsigned int stride = wg_format_get_stride(format);
515 int32_t height = abs(format->u.video.height);
516 int32_t width = format->u.video.width;
518 if (FAILED(MFCreateMediaType(&type)))
519 return NULL;
521 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
522 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, video_formats[i].subtype);
523 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, make_uint64(width, height));
524 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_RATE,
525 make_uint64(format->u.video.fps_n, format->u.video.fps_d));
526 IMFMediaType_SetUINT32(type, &MF_MT_COMPRESSED, FALSE);
527 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
528 IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
530 if (format->u.video.height < 0)
531 stride = -stride;
532 IMFMediaType_SetUINT32(type, &MF_MT_DEFAULT_STRIDE, stride);
534 if (format->u.video.padding.left || format->u.video.padding.right
535 || format->u.video.padding.top || format->u.video.padding.bottom)
537 MFVideoArea aperture =
539 .OffsetX = {.value = format->u.video.padding.left},
540 .OffsetY = {.value = format->u.video.padding.top},
541 .Area.cx = width - format->u.video.padding.right - format->u.video.padding.left,
542 .Area.cy = height - format->u.video.padding.bottom - format->u.video.padding.top,
545 IMFMediaType_SetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
546 (BYTE *)&aperture, sizeof(aperture));
549 return type;
553 FIXME("Unknown video format %#x.\n", format->u.video.format);
554 return NULL;
557 IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
559 switch (format->major_type)
561 case WG_MAJOR_TYPE_AUDIO_MPEG1:
562 case WG_MAJOR_TYPE_AUDIO_MPEG4:
563 case WG_MAJOR_TYPE_AUDIO_WMA:
564 case WG_MAJOR_TYPE_VIDEO_CINEPAK:
565 case WG_MAJOR_TYPE_VIDEO_H264:
566 case WG_MAJOR_TYPE_VIDEO_WMV:
567 case WG_MAJOR_TYPE_VIDEO_INDEO:
568 case WG_MAJOR_TYPE_VIDEO_MPEG1:
569 FIXME("Format %u not implemented!\n", format->major_type);
570 /* fallthrough */
571 case WG_MAJOR_TYPE_UNKNOWN:
572 return NULL;
574 case WG_MAJOR_TYPE_AUDIO:
575 return mf_media_type_from_wg_format_audio(format);
577 case WG_MAJOR_TYPE_VIDEO:
578 return mf_media_type_from_wg_format_video(format);
581 assert(0);
582 return NULL;
585 static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
587 UINT32 rate, channels, channel_mask, depth;
588 unsigned int i;
590 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
592 FIXME("Sample rate is not set.\n");
593 return;
595 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
597 FIXME("Channel count is not set.\n");
598 return;
600 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
602 FIXME("Depth is not set.\n");
603 return;
605 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask)))
607 if (channels == 1)
608 channel_mask = KSAUDIO_SPEAKER_MONO;
609 else if (channels == 2)
610 channel_mask = KSAUDIO_SPEAKER_STEREO;
611 else
613 FIXME("Channel mask is not set.\n");
614 return;
618 format->major_type = WG_MAJOR_TYPE_AUDIO;
619 format->u.audio.channels = channels;
620 format->u.audio.channel_mask = channel_mask;
621 format->u.audio.rate = rate;
623 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
625 if (IsEqualGUID(subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth)
627 format->u.audio.format = audio_formats[i].format;
628 return;
631 FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(subtype), depth);
634 static void mf_media_type_to_wg_format_audio_mpeg4(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
636 /* Audio specific config is stored at after HEAACWAVEINFO in MF_MT_USER_DATA
637 * https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-heaacwaveformat
639 typedef struct
641 WORD wPayloadType;
642 WORD wAudioProfileLevelIndication;
643 WORD wStructType;
644 WORD wReserved1;
645 DWORD dwReserved2;
646 } HEAACWAVEINFO;
647 typedef struct
649 HEAACWAVEINFO wfInfo;
650 BYTE pbAudioSpecificConfig[1];
651 } HEAACWAVEFORMAT;
653 BYTE buffer[64];
654 HEAACWAVEFORMAT *user_data = (HEAACWAVEFORMAT *)buffer;
655 UINT32 codec_data_size;
656 BOOL raw_aac;
658 if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, buffer, sizeof(buffer), &codec_data_size)))
660 FIXME("Codec data is not set.\n");
661 return;
664 raw_aac = IsEqualGUID(subtype, &MFAudioFormat_RAW_AAC);
665 if (!raw_aac)
666 codec_data_size -= min(codec_data_size, offsetof(HEAACWAVEFORMAT, pbAudioSpecificConfig));
667 if (codec_data_size > sizeof(format->u.audio_mpeg4.codec_data))
669 FIXME("Codec data needs %u bytes.\n", codec_data_size);
670 return;
672 if (raw_aac)
673 memcpy(format->u.audio_mpeg4.codec_data, buffer, codec_data_size);
674 else
675 memcpy(format->u.audio_mpeg4.codec_data, user_data->pbAudioSpecificConfig, codec_data_size);
677 format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG4;
679 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &format->u.audio_mpeg4.payload_type)))
680 format->u.audio_mpeg4.payload_type = 0;
682 format->u.audio_mpeg4.codec_data_len = codec_data_size;
685 static enum wg_video_format mf_video_format_to_wg(const GUID *subtype)
687 unsigned int i;
689 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
691 if (IsEqualGUID(subtype, video_formats[i].subtype))
692 return video_formats[i].format;
694 FIXME("Unrecognized video subtype %s.\n", debugstr_guid(subtype));
695 return WG_VIDEO_FORMAT_UNKNOWN;
698 static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
700 UINT64 frame_rate, frame_size;
701 MFVideoArea aperture;
702 UINT32 size, stride;
704 if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
706 FIXME("Frame size is not set.\n");
707 return;
710 format->major_type = WG_MAJOR_TYPE_VIDEO;
711 format->u.video.width = (UINT32)(frame_size >> 32);
712 format->u.video.height = (UINT32)frame_size;
713 format->u.video.fps_n = 1;
714 format->u.video.fps_d = 1;
716 if (SUCCEEDED(IMFMediaType_GetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture,
717 sizeof(aperture), &size)) && size == sizeof(aperture))
719 format->u.video.padding.left = aperture.OffsetX.value;
720 format->u.video.padding.top = aperture.OffsetY.value;
721 format->u.video.padding.right = format->u.video.width - aperture.Area.cx - aperture.OffsetX.value;
722 format->u.video.padding.bottom = format->u.video.height - aperture.Area.cy - aperture.OffsetY.value;
725 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
727 format->u.video.fps_n = (UINT32)(frame_rate >> 32);
728 format->u.video.fps_d = (UINT32)frame_rate;
731 format->u.video.format = mf_video_format_to_wg(subtype);
733 if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_DEFAULT_STRIDE, &stride)))
735 if ((int)stride < 0)
736 format->u.video.height = -format->u.video.height;
738 else if (wg_video_format_is_rgb(format->u.video.format))
740 format->u.video.height = -format->u.video.height;
744 static void mf_media_type_to_wg_format_audio_wma(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
746 UINT32 rate, depth, channels, block_align, bytes_per_second, codec_data_len;
747 BYTE codec_data[64];
748 UINT32 version;
750 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
752 FIXME("Sample rate is not set.\n");
753 return;
755 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
757 FIXME("Channel count is not set.\n");
758 return;
760 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align)))
762 FIXME("Block alignment is not set.\n");
763 return;
765 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
767 FIXME("Depth is not set.\n");
768 return;
770 if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len)))
772 FIXME("Codec data is not set.\n");
773 return;
775 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bytes_per_second)))
777 FIXME("Bitrate is not set.\n");
778 bytes_per_second = 0;
781 if (IsEqualGUID(subtype, &MEDIASUBTYPE_MSAUDIO1))
782 version = 1;
783 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV8))
784 version = 2;
785 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV9))
786 version = 3;
787 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudio_Lossless))
788 version = 4;
789 else
791 assert(0);
792 return;
795 format->major_type = WG_MAJOR_TYPE_AUDIO_WMA;
796 format->u.audio_wma.version = version;
797 format->u.audio_wma.bitrate = bytes_per_second * 8;
798 format->u.audio_wma.rate = rate;
799 format->u.audio_wma.depth = depth;
800 format->u.audio_wma.channels = channels;
801 format->u.audio_wma.block_align = block_align;
802 format->u.audio_wma.codec_data_len = codec_data_len;
803 memcpy(format->u.audio_wma.codec_data, codec_data, codec_data_len);
806 static void mf_media_type_to_wg_format_video_h264(IMFMediaType *type, struct wg_format *format)
808 UINT32 profile, level, codec_data_len;
809 UINT64 frame_rate, frame_size;
810 BYTE *codec_data;
812 memset(format, 0, sizeof(*format));
813 format->major_type = WG_MAJOR_TYPE_VIDEO_H264;
815 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
817 format->u.video_h264.width = frame_size >> 32;
818 format->u.video_h264.height = (UINT32)frame_size;
821 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
823 format->u.video_h264.fps_n = frame_rate >> 32;
824 format->u.video_h264.fps_d = (UINT32)frame_rate;
826 else
828 format->u.video_h264.fps_n = 1;
829 format->u.video_h264.fps_d = 1;
832 if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile)))
833 format->u.video_h264.profile = profile;
835 if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level)))
836 format->u.video_h264.level = level;
838 if (SUCCEEDED(IMFMediaType_GetAllocatedBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, &codec_data, &codec_data_len)))
840 if (codec_data_len <= sizeof(format->u.video_h264.codec_data))
842 format->u.video_h264.codec_data_len = codec_data_len;
843 memcpy(format->u.video_h264.codec_data, codec_data, codec_data_len);
845 else
847 WARN("Codec data buffer too small, codec data size %u.\n", codec_data_len);
849 CoTaskMemFree(codec_data);
853 static void mf_media_type_to_wg_format_video_indeo(IMFMediaType *type, uint32_t version, struct wg_format *format)
855 UINT64 frame_rate, frame_size;
857 memset(format, 0, sizeof(*format));
858 format->major_type = WG_MAJOR_TYPE_VIDEO_INDEO;
860 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
862 format->u.video_indeo.width = frame_size >> 32;
863 format->u.video_indeo.height = (UINT32)frame_size;
866 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
868 format->u.video_indeo.fps_n = frame_rate >> 32;
869 format->u.video_indeo.fps_d = (UINT32)frame_rate;
871 else
873 format->u.video_indeo.fps_n = 1;
874 format->u.video_indeo.fps_d = 1;
877 format->u.video_indeo.version = version;
880 void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
882 GUID major_type, subtype;
884 memset(format, 0, sizeof(*format));
886 if (FAILED(IMFMediaType_GetMajorType(type, &major_type)))
888 FIXME("Major type is not set.\n");
889 return;
891 if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
893 FIXME("Subtype is not set.\n");
894 return;
897 if (IsEqualGUID(&major_type, &MFMediaType_Audio))
899 if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1) ||
900 IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8) ||
901 IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9) ||
902 IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless))
903 mf_media_type_to_wg_format_audio_wma(type, &subtype, format);
904 else if (IsEqualGUID(&subtype, &MFAudioFormat_AAC) || IsEqualGUID(&subtype, &MFAudioFormat_RAW_AAC))
905 mf_media_type_to_wg_format_audio_mpeg4(type, &subtype, format);
906 else
907 mf_media_type_to_wg_format_audio(type, &subtype, format);
909 else if (IsEqualGUID(&major_type, &MFMediaType_Video))
911 if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
912 mf_media_type_to_wg_format_video_h264(type, format);
913 else if (IsEqualGUID(&subtype, &MFVideoFormat_IV50))
914 mf_media_type_to_wg_format_video_indeo(type, 5, format);
915 else
916 mf_media_type_to_wg_format_video(type, &subtype, format);
918 else
919 FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));