winegstreamer: Register AAC decoder MFT stub.
[wine.git] / dlls / winegstreamer / mfplat.c
blob997521768a61d217e538b84cdd84752c605f48ba
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);
41 struct class_factory
43 IClassFactory IClassFactory_iface;
44 LONG refcount;
45 HRESULT (*create_instance)(REFIID riid, void **obj);
48 static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
50 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
53 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
55 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
57 if (IsEqualGUID(riid, &IID_IClassFactory) ||
58 IsEqualGUID(riid, &IID_IUnknown))
60 *obj = iface;
61 IClassFactory_AddRef(iface);
62 return S_OK;
65 WARN("%s is not supported.\n", debugstr_guid(riid));
66 *obj = NULL;
67 return E_NOINTERFACE;
70 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
72 struct class_factory *factory = impl_from_IClassFactory(iface);
73 return InterlockedIncrement(&factory->refcount);
76 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
78 struct class_factory *factory = impl_from_IClassFactory(iface);
79 ULONG refcount = InterlockedDecrement(&factory->refcount);
81 if (!refcount)
82 free(factory);
84 return refcount;
87 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
89 struct class_factory *factory = impl_from_IClassFactory(iface);
91 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), obj);
93 if (outer)
95 *obj = NULL;
96 return CLASS_E_NOAGGREGATION;
99 return factory->create_instance(riid, obj);
102 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock)
104 TRACE("%p, %d.\n", iface, dolock);
105 return S_OK;
108 static const IClassFactoryVtbl class_factory_vtbl =
110 class_factory_QueryInterface,
111 class_factory_AddRef,
112 class_factory_Release,
113 class_factory_CreateInstance,
114 class_factory_LockServer,
117 static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
119 static const struct class_object
121 const GUID *clsid;
122 HRESULT (*create_instance)(REFIID riid, void **obj);
124 class_objects[] =
126 { &CLSID_VideoProcessorMFT, &video_processor_create },
127 { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
128 { &CLSID_MSAACDecMFT, &aac_decoder_create },
129 { &CLSID_MSH264DecoderMFT, &h264_decoder_create },
132 HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
134 struct class_factory *factory;
135 unsigned int i;
136 HRESULT hr;
138 for (i = 0; i < ARRAY_SIZE(class_objects); ++i)
140 if (IsEqualGUID(class_objects[i].clsid, rclsid))
142 if (!(factory = malloc(sizeof(*factory))))
143 return E_OUTOFMEMORY;
145 factory->IClassFactory_iface.lpVtbl = &class_factory_vtbl;
146 factory->refcount = 1;
147 factory->create_instance = class_objects[i].create_instance;
149 hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
150 IClassFactory_Release(&factory->IClassFactory_iface);
151 return hr;
155 return CLASS_E_CLASSNOTAVAILABLE;
158 HRESULT mfplat_DllRegisterServer(void)
160 MFT_REGISTER_TYPE_INFO resampler_types[] =
162 {MFMediaType_Audio, MFAudioFormat_PCM},
163 {MFMediaType_Audio, MFAudioFormat_Float},
166 MFT_REGISTER_TYPE_INFO aac_decoder_input_types[] =
168 {MFMediaType_Audio, MFAudioFormat_AAC},
169 {MFMediaType_Audio, MFAudioFormat_RAW_AAC},
170 {MFMediaType_Audio, MFAudioFormat_ADTS},
172 MFT_REGISTER_TYPE_INFO aac_decoder_output_types[] =
174 {MFMediaType_Audio, MFAudioFormat_Float},
175 {MFMediaType_Audio, MFAudioFormat_PCM},
178 MFT_REGISTER_TYPE_INFO wma_decoder_input_types[] =
180 {MFMediaType_Audio, MEDIASUBTYPE_MSAUDIO1},
181 {MFMediaType_Audio, MFAudioFormat_WMAudioV8},
182 {MFMediaType_Audio, MFAudioFormat_WMAudioV9},
183 {MFMediaType_Audio, MFAudioFormat_WMAudio_Lossless},
185 MFT_REGISTER_TYPE_INFO wma_decoder_output_types[] =
187 {MFMediaType_Audio, MFAudioFormat_PCM},
188 {MFMediaType_Audio, MFAudioFormat_Float},
191 MFT_REGISTER_TYPE_INFO h264_decoder_input_types[] =
193 {MFMediaType_Video, MFVideoFormat_H264},
194 {MFMediaType_Video, MFVideoFormat_H264_ES},
196 MFT_REGISTER_TYPE_INFO h264_decoder_output_types[] =
198 {MFMediaType_Video, MFVideoFormat_NV12},
199 {MFMediaType_Video, MFVideoFormat_YV12},
200 {MFMediaType_Video, MFVideoFormat_IYUV},
201 {MFMediaType_Video, MFVideoFormat_I420},
202 {MFMediaType_Video, MFVideoFormat_YUY2},
205 MFT_REGISTER_TYPE_INFO video_processor_input_types[] =
207 {MFMediaType_Video, MFVideoFormat_IYUV},
208 {MFMediaType_Video, MFVideoFormat_YV12},
209 {MFMediaType_Video, MFVideoFormat_NV12},
210 {MFMediaType_Video, MFVideoFormat_YUY2},
211 {MFMediaType_Video, MFVideoFormat_ARGB32},
212 {MFMediaType_Video, MFVideoFormat_RGB32},
213 {MFMediaType_Video, MFVideoFormat_NV11},
214 {MFMediaType_Video, MFVideoFormat_AYUV},
215 {MFMediaType_Video, MFVideoFormat_UYVY},
216 {MFMediaType_Video, MEDIASUBTYPE_P208},
217 {MFMediaType_Video, MFVideoFormat_RGB24},
218 {MFMediaType_Video, MFVideoFormat_RGB555},
219 {MFMediaType_Video, MFVideoFormat_RGB565},
220 {MFMediaType_Video, MFVideoFormat_RGB8},
221 {MFMediaType_Video, MFVideoFormat_I420},
222 {MFMediaType_Video, MFVideoFormat_Y216},
223 {MFMediaType_Video, MFVideoFormat_v410},
224 {MFMediaType_Video, MFVideoFormat_Y41P},
225 {MFMediaType_Video, MFVideoFormat_Y41T},
226 {MFMediaType_Video, MFVideoFormat_Y42T},
227 {MFMediaType_Video, MFVideoFormat_YVYU},
228 {MFMediaType_Video, MFVideoFormat_420O},
230 MFT_REGISTER_TYPE_INFO video_processor_output_types[] =
232 {MFMediaType_Video, MFVideoFormat_IYUV},
233 {MFMediaType_Video, MFVideoFormat_YV12},
234 {MFMediaType_Video, MFVideoFormat_NV12},
235 {MFMediaType_Video, MFVideoFormat_YUY2},
236 {MFMediaType_Video, MFVideoFormat_ARGB32},
237 {MFMediaType_Video, MFVideoFormat_RGB32},
238 {MFMediaType_Video, MFVideoFormat_NV11},
239 {MFMediaType_Video, MFVideoFormat_AYUV},
240 {MFMediaType_Video, MFVideoFormat_UYVY},
241 {MFMediaType_Video, MEDIASUBTYPE_P208},
242 {MFMediaType_Video, MFVideoFormat_RGB24},
243 {MFMediaType_Video, MFVideoFormat_RGB555},
244 {MFMediaType_Video, MFVideoFormat_RGB565},
245 {MFMediaType_Video, MFVideoFormat_RGB8},
246 {MFMediaType_Video, MFVideoFormat_I420},
247 {MFMediaType_Video, MFVideoFormat_Y216},
248 {MFMediaType_Video, MFVideoFormat_v410},
249 {MFMediaType_Video, MFVideoFormat_Y41P},
250 {MFMediaType_Video, MFVideoFormat_Y41T},
251 {MFMediaType_Video, MFVideoFormat_Y42T},
252 {MFMediaType_Video, MFVideoFormat_YVYU},
255 MFT_REGISTER_TYPE_INFO color_convert_input_types[] =
257 {MFMediaType_Video, MFVideoFormat_YV12},
258 {MFMediaType_Video, MFVideoFormat_YUY2},
259 {MFMediaType_Video, MFVideoFormat_UYVY},
260 {MFMediaType_Video, MFVideoFormat_AYUV},
261 {MFMediaType_Video, MFVideoFormat_NV12},
262 {MFMediaType_Video, DMOVideoFormat_RGB32},
263 {MFMediaType_Video, DMOVideoFormat_RGB565},
264 {MFMediaType_Video, MFVideoFormat_I420},
265 {MFMediaType_Video, MFVideoFormat_IYUV},
266 {MFMediaType_Video, MFVideoFormat_YVYU},
267 {MFMediaType_Video, DMOVideoFormat_RGB24},
268 {MFMediaType_Video, DMOVideoFormat_RGB555},
269 {MFMediaType_Video, DMOVideoFormat_RGB8},
270 {MFMediaType_Video, MEDIASUBTYPE_V216},
271 {MFMediaType_Video, MEDIASUBTYPE_V410},
272 {MFMediaType_Video, MFVideoFormat_NV11},
273 {MFMediaType_Video, MFVideoFormat_Y41P},
274 {MFMediaType_Video, MFVideoFormat_Y41T},
275 {MFMediaType_Video, MFVideoFormat_Y42T},
276 {MFMediaType_Video, MFVideoFormat_YVU9},
278 MFT_REGISTER_TYPE_INFO color_convert_output_types[] =
280 {MFMediaType_Video, MFVideoFormat_YV12},
281 {MFMediaType_Video, MFVideoFormat_YUY2},
282 {MFMediaType_Video, MFVideoFormat_UYVY},
283 {MFMediaType_Video, MFVideoFormat_AYUV},
284 {MFMediaType_Video, MFVideoFormat_NV12},
285 {MFMediaType_Video, DMOVideoFormat_RGB32},
286 {MFMediaType_Video, DMOVideoFormat_RGB565},
287 {MFMediaType_Video, MFVideoFormat_I420},
288 {MFMediaType_Video, MFVideoFormat_IYUV},
289 {MFMediaType_Video, MFVideoFormat_YVYU},
290 {MFMediaType_Video, DMOVideoFormat_RGB24},
291 {MFMediaType_Video, DMOVideoFormat_RGB555},
292 {MFMediaType_Video, DMOVideoFormat_RGB8},
293 {MFMediaType_Video, MEDIASUBTYPE_V216},
294 {MFMediaType_Video, MEDIASUBTYPE_V410},
295 {MFMediaType_Video, MFVideoFormat_NV11},
298 struct mft
300 GUID clsid;
301 GUID category;
302 WCHAR name[MAX_PATH];
303 UINT32 flags;
304 UINT32 input_types_count;
305 MFT_REGISTER_TYPE_INFO *input_types;
306 UINT32 output_types_count;
307 MFT_REGISTER_TYPE_INFO *output_types;
309 mfts[] =
312 CLSID_MSAACDecMFT,
313 MFT_CATEGORY_AUDIO_DECODER,
314 L"Microsoft AAC Audio Decoder MFT",
315 MFT_ENUM_FLAG_SYNCMFT,
316 ARRAY_SIZE(aac_decoder_input_types),
317 aac_decoder_input_types,
318 ARRAY_SIZE(aac_decoder_output_types),
319 aac_decoder_output_types,
322 CLSID_WMADecMediaObject,
323 MFT_CATEGORY_AUDIO_DECODER,
324 L"WMAudio Decoder MFT",
325 MFT_ENUM_FLAG_SYNCMFT,
326 ARRAY_SIZE(wma_decoder_input_types),
327 wma_decoder_input_types,
328 ARRAY_SIZE(wma_decoder_output_types),
329 wma_decoder_output_types,
332 CLSID_MSH264DecoderMFT,
333 MFT_CATEGORY_VIDEO_DECODER,
334 L"Microsoft H264 Video Decoder MFT",
335 MFT_ENUM_FLAG_SYNCMFT,
336 ARRAY_SIZE(h264_decoder_input_types),
337 h264_decoder_input_types,
338 ARRAY_SIZE(h264_decoder_output_types),
339 h264_decoder_output_types,
342 CLSID_VideoProcessorMFT,
343 MFT_CATEGORY_VIDEO_PROCESSOR,
344 L"Microsoft Video Processor MFT",
345 MFT_ENUM_FLAG_SYNCMFT,
346 ARRAY_SIZE(video_processor_input_types),
347 video_processor_input_types,
348 ARRAY_SIZE(video_processor_output_types),
349 video_processor_output_types,
352 CLSID_CResamplerMediaObject,
353 MFT_CATEGORY_AUDIO_EFFECT,
354 L"Resampler MFT",
355 MFT_ENUM_FLAG_SYNCMFT,
356 ARRAY_SIZE(resampler_types),
357 resampler_types,
358 ARRAY_SIZE(resampler_types),
359 resampler_types,
362 CLSID_CColorConvertDMO,
363 MFT_CATEGORY_VIDEO_EFFECT,
364 L"Color Converter MFT",
365 MFT_ENUM_FLAG_SYNCMFT,
366 ARRAY_SIZE(color_convert_input_types),
367 color_convert_input_types,
368 ARRAY_SIZE(color_convert_output_types),
369 color_convert_output_types,
373 unsigned int i;
374 HRESULT hr;
376 for (i = 0; i < ARRAY_SIZE(mfts); i++)
378 hr = MFTRegister(mfts[i].clsid, mfts[i].category, mfts[i].name, mfts[i].flags, mfts[i].input_types_count,
379 mfts[i].input_types, mfts[i].output_types_count, mfts[i].output_types, NULL);
381 if (FAILED(hr))
383 FIXME("Failed to register MFT, hr %#lx.\n", hr);
384 return hr;
388 return S_OK;
391 static const struct
393 const GUID *subtype;
394 enum wg_video_format format;
396 video_formats[] =
398 {&MFVideoFormat_ARGB32, WG_VIDEO_FORMAT_BGRA},
399 {&MFVideoFormat_RGB32, WG_VIDEO_FORMAT_BGRx},
400 {&MFVideoFormat_RGB24, WG_VIDEO_FORMAT_BGR},
401 {&MFVideoFormat_RGB555, WG_VIDEO_FORMAT_RGB15},
402 {&MFVideoFormat_RGB565, WG_VIDEO_FORMAT_RGB16},
403 {&MFVideoFormat_AYUV, WG_VIDEO_FORMAT_AYUV},
404 {&MFVideoFormat_I420, WG_VIDEO_FORMAT_I420},
405 {&MFVideoFormat_IYUV, WG_VIDEO_FORMAT_I420},
406 {&MFVideoFormat_NV12, WG_VIDEO_FORMAT_NV12},
407 {&MFVideoFormat_UYVY, WG_VIDEO_FORMAT_UYVY},
408 {&MFVideoFormat_YUY2, WG_VIDEO_FORMAT_YUY2},
409 {&MFVideoFormat_YV12, WG_VIDEO_FORMAT_YV12},
410 {&MFVideoFormat_YVYU, WG_VIDEO_FORMAT_YVYU},
413 static const struct
415 const GUID *subtype;
416 UINT32 depth;
417 enum wg_audio_format format;
419 audio_formats[] =
421 {&MFAudioFormat_PCM, 8, WG_AUDIO_FORMAT_U8},
422 {&MFAudioFormat_PCM, 16, WG_AUDIO_FORMAT_S16LE},
423 {&MFAudioFormat_PCM, 24, WG_AUDIO_FORMAT_S24LE},
424 {&MFAudioFormat_PCM, 32, WG_AUDIO_FORMAT_S32LE},
425 {&MFAudioFormat_Float, 32, WG_AUDIO_FORMAT_F32LE},
426 {&MFAudioFormat_Float, 64, WG_AUDIO_FORMAT_F64LE},
429 static inline UINT64 make_uint64(UINT32 high, UINT32 low)
431 return ((UINT64)high << 32) | low;
434 static IMFMediaType *mf_media_type_from_wg_format_audio(const struct wg_format *format)
436 unsigned int i, block_align;
437 IMFMediaType *type;
439 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
441 if (format->u.audio.format == audio_formats[i].format)
443 if (FAILED(MFCreateMediaType(&type)))
444 return NULL;
446 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
447 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, audio_formats[i].subtype);
448 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, audio_formats[i].depth);
449 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->u.audio.rate);
450 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, format->u.audio.channels);
451 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, format->u.audio.channel_mask);
452 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
454 block_align = format->u.audio.channels * audio_formats[i].depth / 8;
455 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, block_align);
456 IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, block_align * format->u.audio.rate);
458 return type;
462 FIXME("Unknown audio format %#x.\n", format->u.audio.format);
463 return NULL;
466 static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format *format)
468 IMFMediaType *type;
469 unsigned int i;
471 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
473 if (format->u.video.format == video_formats[i].format)
475 if (FAILED(MFCreateMediaType(&type)))
476 return NULL;
478 IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
479 IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, video_formats[i].subtype);
480 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE,
481 make_uint64(format->u.video.width, format->u.video.height));
482 IMFMediaType_SetUINT64(type, &MF_MT_FRAME_RATE,
483 make_uint64(format->u.video.fps_n, format->u.video.fps_d));
484 IMFMediaType_SetUINT32(type, &MF_MT_COMPRESSED, FALSE);
485 IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
486 IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
488 if (!IsRectEmpty(&format->u.video.padding))
490 MFVideoArea aperture =
492 .OffsetX = {.value = format->u.video.padding.left},
493 .OffsetY = {.value = format->u.video.padding.top},
494 .Area.cx = format->u.video.width - format->u.video.padding.right - format->u.video.padding.left,
495 .Area.cy = format->u.video.height - format->u.video.padding.bottom - format->u.video.padding.top,
498 IMFMediaType_SetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
499 (BYTE *)&aperture, sizeof(aperture));
502 return type;
506 FIXME("Unknown video format %#x.\n", format->u.video.format);
507 return NULL;
510 IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
512 switch (format->major_type)
514 case WG_MAJOR_TYPE_AUDIO_MPEG1:
515 case WG_MAJOR_TYPE_AUDIO_WMA:
516 case WG_MAJOR_TYPE_VIDEO_CINEPAK:
517 case WG_MAJOR_TYPE_VIDEO_H264:
518 FIXME("Format %u not implemented!\n", format->major_type);
519 /* fallthrough */
520 case WG_MAJOR_TYPE_UNKNOWN:
521 return NULL;
523 case WG_MAJOR_TYPE_AUDIO:
524 return mf_media_type_from_wg_format_audio(format);
526 case WG_MAJOR_TYPE_VIDEO:
527 return mf_media_type_from_wg_format_video(format);
530 assert(0);
531 return NULL;
534 static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
536 UINT32 rate, channels, channel_mask, depth;
537 unsigned int i;
539 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
541 FIXME("Sample rate is not set.\n");
542 return;
544 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
546 FIXME("Channel count is not set.\n");
547 return;
549 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
551 FIXME("Depth is not set.\n");
552 return;
554 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask)))
556 if (channels == 1)
557 channel_mask = KSAUDIO_SPEAKER_MONO;
558 else if (channels == 2)
559 channel_mask = KSAUDIO_SPEAKER_STEREO;
560 else
562 FIXME("Channel mask is not set.\n");
563 return;
567 format->major_type = WG_MAJOR_TYPE_AUDIO;
568 format->u.audio.channels = channels;
569 format->u.audio.channel_mask = channel_mask;
570 format->u.audio.rate = rate;
572 for (i = 0; i < ARRAY_SIZE(audio_formats); ++i)
574 if (IsEqualGUID(subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth)
576 format->u.audio.format = audio_formats[i].format;
577 return;
580 FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(subtype), depth);
583 static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
585 UINT64 frame_rate, frame_size;
586 MFVideoArea aperture;
587 unsigned int i;
588 UINT32 size;
590 if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
592 FIXME("Frame size is not set.\n");
593 return;
596 format->major_type = WG_MAJOR_TYPE_VIDEO;
597 format->u.video.width = (UINT32)(frame_size >> 32);
598 format->u.video.height = (UINT32)frame_size;
599 format->u.video.fps_n = 1;
600 format->u.video.fps_d = 1;
602 if (SUCCEEDED(IMFMediaType_GetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture,
603 sizeof(aperture), &size)) && size == sizeof(aperture))
605 format->u.video.padding.left = aperture.OffsetX.value;
606 format->u.video.padding.top = aperture.OffsetY.value;
607 format->u.video.padding.right = format->u.video.width - aperture.Area.cx - aperture.OffsetX.value;
608 format->u.video.padding.bottom = format->u.video.height - aperture.Area.cy - aperture.OffsetY.value;
611 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
613 format->u.video.fps_n = (UINT32)(frame_rate >> 32);
614 format->u.video.fps_d = (UINT32)frame_rate;
617 for (i = 0; i < ARRAY_SIZE(video_formats); ++i)
619 if (IsEqualGUID(subtype, video_formats[i].subtype))
621 format->u.video.format = video_formats[i].format;
622 return;
625 FIXME("Unrecognized video subtype %s.\n", debugstr_guid(subtype));
628 static void mf_media_type_to_wg_format_audio_wma(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
630 UINT32 rate, depth, channels, block_align, bytes_per_second, codec_data_len;
631 BYTE codec_data[64];
632 UINT32 version;
634 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
636 FIXME("Sample rate is not set.\n");
637 return;
639 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
641 FIXME("Channel count is not set.\n");
642 return;
644 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align)))
646 FIXME("Block alignment is not set.\n");
647 return;
649 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
651 FIXME("Depth is not set.\n");
652 return;
654 if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len)))
656 FIXME("Codec data is not set.\n");
657 return;
659 if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bytes_per_second)))
661 FIXME("Bitrate is not set.\n");
662 bytes_per_second = 0;
665 if (IsEqualGUID(subtype, &MEDIASUBTYPE_MSAUDIO1))
666 version = 1;
667 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV8))
668 version = 2;
669 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV9))
670 version = 3;
671 else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudio_Lossless))
672 version = 4;
673 else
675 assert(0);
676 return;
679 format->major_type = WG_MAJOR_TYPE_AUDIO_WMA;
680 format->u.audio_wma.version = version;
681 format->u.audio_wma.bitrate = bytes_per_second * 8;
682 format->u.audio_wma.rate = rate;
683 format->u.audio_wma.depth = depth;
684 format->u.audio_wma.channels = channels;
685 format->u.audio_wma.block_align = block_align;
686 format->u.audio_wma.codec_data_len = codec_data_len;
687 memcpy(format->u.audio_wma.codec_data, codec_data, codec_data_len);
690 static void mf_media_type_to_wg_format_video_h264(IMFMediaType *type, struct wg_format *format)
692 UINT64 frame_rate, frame_size;
693 UINT32 profile, level;
695 memset(format, 0, sizeof(*format));
696 format->major_type = WG_MAJOR_TYPE_VIDEO_H264;
698 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
700 format->u.video_h264.width = frame_size >> 32;
701 format->u.video_h264.height = (UINT32)frame_size;
704 if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
706 format->u.video_h264.fps_n = frame_rate >> 32;
707 format->u.video_h264.fps_d = (UINT32)frame_rate;
709 else
711 format->u.video_h264.fps_n = 1;
712 format->u.video_h264.fps_d = 1;
715 if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile)))
716 format->u.video_h264.profile = profile;
718 if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level)))
719 format->u.video_h264.level = level;
722 void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
724 GUID major_type, subtype;
726 memset(format, 0, sizeof(*format));
728 if (FAILED(IMFMediaType_GetMajorType(type, &major_type)))
730 FIXME("Major type is not set.\n");
731 return;
733 if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
735 FIXME("Subtype is not set.\n");
736 return;
739 if (IsEqualGUID(&major_type, &MFMediaType_Audio))
741 if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1) ||
742 IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8) ||
743 IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9) ||
744 IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless))
745 mf_media_type_to_wg_format_audio_wma(type, &subtype, format);
746 else
747 mf_media_type_to_wg_format_audio(type, &subtype, format);
749 else if (IsEqualGUID(&major_type, &MFMediaType_Video))
751 if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
752 mf_media_type_to_wg_format_video_h264(type, format);
753 else
754 mf_media_type_to_wg_format_video(type, &subtype, format);
756 else
757 FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));