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"
24 #include "wmcodecdsp.h"
26 #include "d3d9types.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
);
43 IClassFactory IClassFactory_iface
;
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
))
61 IClassFactory_AddRef(iface
);
65 WARN("%s is not supported.\n", debugstr_guid(riid
));
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
);
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
);
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
);
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
122 HRESULT (*create_instance
)(REFIID riid
, void **obj
);
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
;
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
);
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
},
302 WCHAR name
[MAX_PATH
];
304 UINT32 input_types_count
;
305 MFT_REGISTER_TYPE_INFO
*input_types
;
306 UINT32 output_types_count
;
307 MFT_REGISTER_TYPE_INFO
*output_types
;
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
,
355 MFT_ENUM_FLAG_SYNCMFT
,
356 ARRAY_SIZE(resampler_types
),
358 ARRAY_SIZE(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
,
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
);
383 FIXME("Failed to register MFT, hr %#lx.\n", hr
);
394 enum wg_video_format format
;
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
},
417 enum wg_audio_format format
;
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
;
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
)))
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
);
462 FIXME("Unknown audio format %#x.\n", format
->u
.audio
.format
);
466 static IMFMediaType
*mf_media_type_from_wg_format_video(const struct wg_format
*format
)
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
)))
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
));
506 FIXME("Unknown video format %#x.\n", format
->u
.video
.format
);
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
);
520 case WG_MAJOR_TYPE_UNKNOWN
:
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
);
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
;
539 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &rate
)))
541 FIXME("Sample rate is not set.\n");
544 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channels
)))
546 FIXME("Channel count is not set.\n");
549 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &depth
)))
551 FIXME("Depth is not set.\n");
554 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_CHANNEL_MASK
, &channel_mask
)))
557 channel_mask
= KSAUDIO_SPEAKER_MONO
;
558 else if (channels
== 2)
559 channel_mask
= KSAUDIO_SPEAKER_STEREO
;
562 FIXME("Channel mask is not set.\n");
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
;
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
;
590 if (FAILED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_SIZE
, &frame_size
)))
592 FIXME("Frame size is not set.\n");
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
;
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
;
634 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &rate
)))
636 FIXME("Sample rate is not set.\n");
639 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channels
)))
641 FIXME("Channel count is not set.\n");
644 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &block_align
)))
646 FIXME("Block alignment is not set.\n");
649 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &depth
)))
651 FIXME("Depth is not set.\n");
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");
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
))
667 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudioV8
))
669 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudioV9
))
671 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudio_Lossless
))
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
;
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");
733 if (FAILED(IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
)))
735 FIXME("Subtype is not set.\n");
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
);
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
);
754 mf_media_type_to_wg_format_video(type
, &subtype
, format
);
757 FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type
));