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
);
40 DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S
,MAKEFOURCC('V','C','1','S'));
41 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IV50
,MAKEFOURCC('I','V','5','0'));
45 IClassFactory IClassFactory_iface
;
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
))
63 IClassFactory_AddRef(iface
);
67 WARN("%s is not supported.\n", debugstr_guid(riid
));
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
);
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
);
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
);
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
124 HRESULT (*create_instance
)(REFIID riid
, void **obj
);
128 { &CLSID_VideoProcessorMFT
, &video_processor_create
},
129 { &CLSID_GStreamerByteStreamHandler
, &winegstreamer_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
;
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
);
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
},
331 WCHAR name
[MAX_PATH
];
333 UINT32 input_types_count
;
334 MFT_REGISTER_TYPE_INFO
*input_types
;
335 UINT32 output_types_count
;
336 MFT_REGISTER_TYPE_INFO
*output_types
;
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
,
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
,
394 MFT_ENUM_FLAG_SYNCMFT
,
395 ARRAY_SIZE(resampler_types
),
397 ARRAY_SIZE(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
,
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
);
422 FIXME("Failed to register MFT, hr %#lx.\n", hr
);
433 enum wg_video_format format
;
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
},
456 enum wg_audio_format format
;
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
;
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
)))
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
);
501 FIXME("Unknown audio format %#x.\n", format
->u
.audio
.format
);
505 static IMFMediaType
*mf_media_type_from_wg_format_video(const struct wg_format
*format
)
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
)))
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)
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
));
553 FIXME("Unknown video format %#x.\n", format
->u
.video
.format
);
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 FIXME("Format %u not implemented!\n", format
->major_type
);
570 case WG_MAJOR_TYPE_UNKNOWN
:
573 case WG_MAJOR_TYPE_AUDIO
:
574 return mf_media_type_from_wg_format_audio(format
);
576 case WG_MAJOR_TYPE_VIDEO
:
577 return mf_media_type_from_wg_format_video(format
);
584 static void mf_media_type_to_wg_format_audio(IMFMediaType
*type
, const GUID
*subtype
, struct wg_format
*format
)
586 UINT32 rate
, channels
, channel_mask
, depth
;
589 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &rate
)))
591 FIXME("Sample rate is not set.\n");
594 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channels
)))
596 FIXME("Channel count is not set.\n");
599 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &depth
)))
601 FIXME("Depth is not set.\n");
604 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_CHANNEL_MASK
, &channel_mask
)))
607 channel_mask
= KSAUDIO_SPEAKER_MONO
;
608 else if (channels
== 2)
609 channel_mask
= KSAUDIO_SPEAKER_STEREO
;
612 FIXME("Channel mask is not set.\n");
617 format
->major_type
= WG_MAJOR_TYPE_AUDIO
;
618 format
->u
.audio
.channels
= channels
;
619 format
->u
.audio
.channel_mask
= channel_mask
;
620 format
->u
.audio
.rate
= rate
;
622 for (i
= 0; i
< ARRAY_SIZE(audio_formats
); ++i
)
624 if (IsEqualGUID(subtype
, audio_formats
[i
].subtype
) && depth
== audio_formats
[i
].depth
)
626 format
->u
.audio
.format
= audio_formats
[i
].format
;
630 FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(subtype
), depth
);
633 static void mf_media_type_to_wg_format_audio_mpeg4(IMFMediaType
*type
, const GUID
*subtype
, struct wg_format
*format
)
635 /* Audio specific config is stored at after HEAACWAVEINFO in MF_MT_USER_DATA
636 * https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-heaacwaveformat
641 WORD wAudioProfileLevelIndication
;
648 HEAACWAVEINFO wfInfo
;
649 BYTE pbAudioSpecificConfig
[1];
653 HEAACWAVEFORMAT
*user_data
= (HEAACWAVEFORMAT
*)buffer
;
654 UINT32 codec_data_size
;
657 if (FAILED(IMFMediaType_GetBlob(type
, &MF_MT_USER_DATA
, buffer
, sizeof(buffer
), &codec_data_size
)))
659 FIXME("Codec data is not set.\n");
663 raw_aac
= IsEqualGUID(subtype
, &MFAudioFormat_RAW_AAC
);
665 codec_data_size
-= min(codec_data_size
, offsetof(HEAACWAVEFORMAT
, pbAudioSpecificConfig
));
666 if (codec_data_size
> sizeof(format
->u
.audio_mpeg4
.codec_data
))
668 FIXME("Codec data needs %u bytes.\n", codec_data_size
);
672 memcpy(format
->u
.audio_mpeg4
.codec_data
, buffer
, codec_data_size
);
674 memcpy(format
->u
.audio_mpeg4
.codec_data
, user_data
->pbAudioSpecificConfig
, codec_data_size
);
676 format
->major_type
= WG_MAJOR_TYPE_AUDIO_MPEG4
;
678 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AAC_PAYLOAD_TYPE
, &format
->u
.audio_mpeg4
.payload_type
)))
679 format
->u
.audio_mpeg4
.payload_type
= 0;
681 format
->u
.audio_mpeg4
.codec_data_len
= codec_data_size
;
684 static enum wg_video_format
mf_video_format_to_wg(const GUID
*subtype
)
688 for (i
= 0; i
< ARRAY_SIZE(video_formats
); ++i
)
690 if (IsEqualGUID(subtype
, video_formats
[i
].subtype
))
691 return video_formats
[i
].format
;
693 FIXME("Unrecognized video subtype %s.\n", debugstr_guid(subtype
));
694 return WG_VIDEO_FORMAT_UNKNOWN
;
697 static void mf_media_type_to_wg_format_video(IMFMediaType
*type
, const GUID
*subtype
, struct wg_format
*format
)
699 UINT64 frame_rate
, frame_size
;
700 MFVideoArea aperture
;
703 if (FAILED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_SIZE
, &frame_size
)))
705 FIXME("Frame size is not set.\n");
709 format
->major_type
= WG_MAJOR_TYPE_VIDEO
;
710 format
->u
.video
.width
= (UINT32
)(frame_size
>> 32);
711 format
->u
.video
.height
= (UINT32
)frame_size
;
712 format
->u
.video
.fps_n
= 1;
713 format
->u
.video
.fps_d
= 1;
715 if (SUCCEEDED(IMFMediaType_GetBlob(type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, (BYTE
*)&aperture
,
716 sizeof(aperture
), &size
)) && size
== sizeof(aperture
))
718 format
->u
.video
.padding
.left
= aperture
.OffsetX
.value
;
719 format
->u
.video
.padding
.top
= aperture
.OffsetY
.value
;
720 format
->u
.video
.padding
.right
= format
->u
.video
.width
- aperture
.Area
.cx
- aperture
.OffsetX
.value
;
721 format
->u
.video
.padding
.bottom
= format
->u
.video
.height
- aperture
.Area
.cy
- aperture
.OffsetY
.value
;
724 if (SUCCEEDED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_RATE
, &frame_rate
)) && (UINT32
)frame_rate
)
726 format
->u
.video
.fps_n
= (UINT32
)(frame_rate
>> 32);
727 format
->u
.video
.fps_d
= (UINT32
)frame_rate
;
730 format
->u
.video
.format
= mf_video_format_to_wg(subtype
);
732 if (SUCCEEDED(IMFMediaType_GetUINT32(type
, &MF_MT_DEFAULT_STRIDE
, &stride
)))
735 format
->u
.video
.height
= -format
->u
.video
.height
;
737 else if (wg_video_format_is_rgb(format
->u
.video
.format
))
739 format
->u
.video
.height
= -format
->u
.video
.height
;
743 static void mf_media_type_to_wg_format_audio_wma(IMFMediaType
*type
, const GUID
*subtype
, struct wg_format
*format
)
745 UINT32 rate
, depth
, channels
, block_align
, bytes_per_second
, codec_data_len
;
749 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &rate
)))
751 FIXME("Sample rate is not set.\n");
754 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channels
)))
756 FIXME("Channel count is not set.\n");
759 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &block_align
)))
761 FIXME("Block alignment is not set.\n");
764 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &depth
)))
766 FIXME("Depth is not set.\n");
769 if (FAILED(IMFMediaType_GetBlob(type
, &MF_MT_USER_DATA
, codec_data
, sizeof(codec_data
), &codec_data_len
)))
771 FIXME("Codec data is not set.\n");
774 if (FAILED(IMFMediaType_GetUINT32(type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, &bytes_per_second
)))
776 FIXME("Bitrate is not set.\n");
777 bytes_per_second
= 0;
780 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_MSAUDIO1
))
782 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudioV8
))
784 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudioV9
))
786 else if (IsEqualGUID(subtype
, &MFAudioFormat_WMAudio_Lossless
))
794 format
->major_type
= WG_MAJOR_TYPE_AUDIO_WMA
;
795 format
->u
.audio_wma
.version
= version
;
796 format
->u
.audio_wma
.bitrate
= bytes_per_second
* 8;
797 format
->u
.audio_wma
.rate
= rate
;
798 format
->u
.audio_wma
.depth
= depth
;
799 format
->u
.audio_wma
.channels
= channels
;
800 format
->u
.audio_wma
.block_align
= block_align
;
801 format
->u
.audio_wma
.codec_data_len
= codec_data_len
;
802 memcpy(format
->u
.audio_wma
.codec_data
, codec_data
, codec_data_len
);
805 static void mf_media_type_to_wg_format_video_h264(IMFMediaType
*type
, struct wg_format
*format
)
807 UINT64 frame_rate
, frame_size
;
808 UINT32 profile
, level
;
810 memset(format
, 0, sizeof(*format
));
811 format
->major_type
= WG_MAJOR_TYPE_VIDEO_H264
;
813 if (SUCCEEDED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_SIZE
, &frame_size
)))
815 format
->u
.video_h264
.width
= frame_size
>> 32;
816 format
->u
.video_h264
.height
= (UINT32
)frame_size
;
819 if (SUCCEEDED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_RATE
, &frame_rate
)) && (UINT32
)frame_rate
)
821 format
->u
.video_h264
.fps_n
= frame_rate
>> 32;
822 format
->u
.video_h264
.fps_d
= (UINT32
)frame_rate
;
826 format
->u
.video_h264
.fps_n
= 1;
827 format
->u
.video_h264
.fps_d
= 1;
830 if (SUCCEEDED(IMFMediaType_GetUINT32(type
, &MF_MT_MPEG2_PROFILE
, &profile
)))
831 format
->u
.video_h264
.profile
= profile
;
833 if (SUCCEEDED(IMFMediaType_GetUINT32(type
, &MF_MT_MPEG2_LEVEL
, &level
)))
834 format
->u
.video_h264
.level
= level
;
837 static void mf_media_type_to_wg_format_video_indeo(IMFMediaType
*type
, uint32_t version
, struct wg_format
*format
)
839 UINT64 frame_rate
, frame_size
;
841 memset(format
, 0, sizeof(*format
));
842 format
->major_type
= WG_MAJOR_TYPE_VIDEO_INDEO
;
844 if (SUCCEEDED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_SIZE
, &frame_size
)))
846 format
->u
.video_indeo
.width
= frame_size
>> 32;
847 format
->u
.video_indeo
.height
= (UINT32
)frame_size
;
850 if (SUCCEEDED(IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_RATE
, &frame_rate
)) && (UINT32
)frame_rate
)
852 format
->u
.video_indeo
.fps_n
= frame_rate
>> 32;
853 format
->u
.video_indeo
.fps_d
= (UINT32
)frame_rate
;
857 format
->u
.video_indeo
.fps_n
= 1;
858 format
->u
.video_indeo
.fps_d
= 1;
861 format
->u
.video_indeo
.version
= version
;
864 void mf_media_type_to_wg_format(IMFMediaType
*type
, struct wg_format
*format
)
866 GUID major_type
, subtype
;
868 memset(format
, 0, sizeof(*format
));
870 if (FAILED(IMFMediaType_GetMajorType(type
, &major_type
)))
872 FIXME("Major type is not set.\n");
875 if (FAILED(IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
)))
877 FIXME("Subtype is not set.\n");
881 if (IsEqualGUID(&major_type
, &MFMediaType_Audio
))
883 if (IsEqualGUID(&subtype
, &MEDIASUBTYPE_MSAUDIO1
) ||
884 IsEqualGUID(&subtype
, &MFAudioFormat_WMAudioV8
) ||
885 IsEqualGUID(&subtype
, &MFAudioFormat_WMAudioV9
) ||
886 IsEqualGUID(&subtype
, &MFAudioFormat_WMAudio_Lossless
))
887 mf_media_type_to_wg_format_audio_wma(type
, &subtype
, format
);
888 else if (IsEqualGUID(&subtype
, &MFAudioFormat_AAC
) || IsEqualGUID(&subtype
, &MFAudioFormat_RAW_AAC
))
889 mf_media_type_to_wg_format_audio_mpeg4(type
, &subtype
, format
);
891 mf_media_type_to_wg_format_audio(type
, &subtype
, format
);
893 else if (IsEqualGUID(&major_type
, &MFMediaType_Video
))
895 if (IsEqualGUID(&subtype
, &MFVideoFormat_H264
))
896 mf_media_type_to_wg_format_video_h264(type
, format
);
897 else if (IsEqualGUID(&subtype
, &MFVideoFormat_IV50
))
898 mf_media_type_to_wg_format_video_indeo(type
, 5, format
);
900 mf_media_type_to_wg_format_video(type
, &subtype
, format
);
903 FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type
));