nsiproxy.sys: Implement change notifications for NSI_IP_UNICAST_TABLE.
[wine.git] / dlls / winegstreamer / main.c
bloba92d440c42fc2b7efcf3484beaf32035162137ce
1 /* GStreamer Base Functions
3 * Copyright 2002 Lionel Ulmer
4 * Copyright 2010 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WINE_NO_NAMELESS_EXTENSION
23 #define EXTERN_GUID DEFINE_GUID
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "initguid.h"
28 #include "gst_private.h"
29 #include "winternl.h"
30 #include "rpcproxy.h"
31 #include "dmoreg.h"
32 #include "gst_guids.h"
33 #include "wmcodecdsp.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
37 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
38 DEFINE_GUID(MEDIASUBTYPE_VC1S,MAKEFOURCC('V','C','1','S'),0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
40 static const GUID MEDIASUBTYPE_MP3 = {0x00000055, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
42 bool array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
44 unsigned int new_capacity, max_capacity;
45 void *new_elements;
47 if (count <= *capacity)
48 return TRUE;
50 max_capacity = ~(SIZE_T)0 / size;
51 if (count > max_capacity)
52 return FALSE;
54 new_capacity = max(4, *capacity);
55 while (new_capacity < count && new_capacity <= max_capacity / 2)
56 new_capacity *= 2;
57 if (new_capacity < count)
58 new_capacity = max_capacity;
60 if (!(new_elements = realloc(*elements, new_capacity * size)))
61 return FALSE;
63 *elements = new_elements;
64 *capacity = new_capacity;
66 return TRUE;
69 wg_parser_t wg_parser_create(enum wg_parser_type type)
71 struct wg_parser_create_params params =
73 .type = type,
74 .err_on = ERR_ON(quartz),
75 .warn_on = WARN_ON(quartz),
78 TRACE("type %#x.\n", type);
80 if (WINE_UNIX_CALL(unix_wg_parser_create, &params))
81 return 0;
83 TRACE("Returning parser %#I64x.\n", params.parser);
85 return params.parser;
88 void wg_parser_destroy(wg_parser_t parser)
90 TRACE("parser %#I64x.\n", parser);
92 WINE_UNIX_CALL(unix_wg_parser_destroy, &parser);
95 HRESULT wg_parser_connect(wg_parser_t parser, uint64_t file_size)
97 struct wg_parser_connect_params params =
99 .parser = parser,
100 .file_size = file_size,
103 TRACE("parser %#I64x, file_size %I64u.\n", parser, file_size);
105 return WINE_UNIX_CALL(unix_wg_parser_connect, &params);
108 void wg_parser_disconnect(wg_parser_t parser)
110 TRACE("parser %#I64x.\n", parser);
112 WINE_UNIX_CALL(unix_wg_parser_disconnect, &parser);
115 bool wg_parser_get_next_read_offset(wg_parser_t parser, uint64_t *offset, uint32_t *size)
117 struct wg_parser_get_next_read_offset_params params =
119 .parser = parser,
122 TRACE("parser %#I64x, offset %p, size %p.\n", parser, offset, size);
124 if (WINE_UNIX_CALL(unix_wg_parser_get_next_read_offset, &params))
125 return false;
126 *offset = params.offset;
127 *size = params.size;
128 return true;
131 void wg_parser_push_data(wg_parser_t parser, const void *data, uint32_t size)
133 struct wg_parser_push_data_params params =
135 .parser = parser,
136 .data = data,
137 .size = size,
140 TRACE("parser %#I64x, data %p, size %u.\n", parser, data, size);
142 WINE_UNIX_CALL(unix_wg_parser_push_data, &params);
145 uint32_t wg_parser_get_stream_count(wg_parser_t parser)
147 struct wg_parser_get_stream_count_params params =
149 .parser = parser,
152 TRACE("parser %#I64x.\n", parser);
154 WINE_UNIX_CALL(unix_wg_parser_get_stream_count, &params);
155 return params.count;
158 wg_parser_stream_t wg_parser_get_stream(wg_parser_t parser, uint32_t index)
160 struct wg_parser_get_stream_params params =
162 .parser = parser,
163 .index = index,
166 TRACE("parser %#I64x, index %u.\n", parser, index);
168 WINE_UNIX_CALL(unix_wg_parser_get_stream, &params);
170 TRACE("Returning stream %#I64x.\n", params.stream);
171 return params.stream;
174 void wg_parser_stream_get_preferred_format(wg_parser_stream_t stream, struct wg_format *format)
176 struct wg_parser_stream_get_preferred_format_params params =
178 .stream = stream,
179 .format = format,
182 TRACE("stream %#I64x, format %p.\n", stream, format);
184 WINE_UNIX_CALL(unix_wg_parser_stream_get_preferred_format, &params);
187 void wg_parser_stream_get_codec_format(wg_parser_stream_t stream, struct wg_format *format)
189 struct wg_parser_stream_get_codec_format_params params =
191 .stream = stream,
192 .format = format,
195 TRACE("stream %#I64x, format %p.\n", stream, format);
197 WINE_UNIX_CALL(unix_wg_parser_stream_get_codec_format, &params);
200 void wg_parser_stream_enable(wg_parser_stream_t stream, const struct wg_format *format)
202 struct wg_parser_stream_enable_params params =
204 .stream = stream,
205 .format = format,
208 TRACE("stream %#I64x, format %p.\n", stream, format);
210 WINE_UNIX_CALL(unix_wg_parser_stream_enable, &params);
213 void wg_parser_stream_disable(wg_parser_stream_t stream)
215 TRACE("stream %#I64x.\n", stream);
217 WINE_UNIX_CALL(unix_wg_parser_stream_disable, &stream);
220 bool wg_parser_stream_get_buffer(wg_parser_t parser, wg_parser_stream_t stream,
221 struct wg_parser_buffer *buffer)
223 struct wg_parser_stream_get_buffer_params params =
225 .parser = parser,
226 .stream = stream,
227 .buffer = buffer,
230 TRACE("parser %#I64x, stream %#I64x, buffer %p.\n", parser, stream, buffer);
232 return !WINE_UNIX_CALL(unix_wg_parser_stream_get_buffer, &params);
235 bool wg_parser_stream_copy_buffer(wg_parser_stream_t stream,
236 void *data, uint32_t offset, uint32_t size)
238 struct wg_parser_stream_copy_buffer_params params =
240 .stream = stream,
241 .data = data,
242 .offset = offset,
243 .size = size,
246 TRACE("stream %#I64x, data %p, offset %u, size %u.\n", stream, data, offset, size);
248 return !WINE_UNIX_CALL(unix_wg_parser_stream_copy_buffer, &params);
251 void wg_parser_stream_release_buffer(wg_parser_stream_t stream)
253 TRACE("stream %#I64x.\n", stream);
255 WINE_UNIX_CALL(unix_wg_parser_stream_release_buffer, &stream);
258 void wg_parser_stream_notify_qos(wg_parser_stream_t stream,
259 bool underflow, double proportion, int64_t diff, uint64_t timestamp)
261 struct wg_parser_stream_notify_qos_params params =
263 .stream = stream,
264 .underflow = underflow,
265 .proportion = proportion,
266 .diff = diff,
267 .timestamp = timestamp,
270 TRACE("stream %#I64x, underflow %d, proportion %.16e, diff %I64d, timestamp %I64u.\n",
271 stream, underflow, proportion, diff, timestamp);
273 WINE_UNIX_CALL(unix_wg_parser_stream_notify_qos, &params);
276 uint64_t wg_parser_stream_get_duration(wg_parser_stream_t stream)
278 struct wg_parser_stream_get_duration_params params =
280 .stream = stream,
283 TRACE("stream %#I64x.\n", stream);
285 WINE_UNIX_CALL(unix_wg_parser_stream_get_duration, &params);
287 TRACE("Returning duration %I64u.\n", params.duration);
288 return params.duration;
291 char *wg_parser_stream_get_tag(wg_parser_stream_t stream, enum wg_parser_tag tag)
293 uint32_t size = 0;
294 struct wg_parser_stream_get_tag_params params =
296 .stream = stream,
297 .tag = tag,
298 .size = &size,
300 char *buffer;
302 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag, &params) != STATUS_BUFFER_TOO_SMALL)
303 return NULL;
304 if (!(buffer = malloc(size)))
306 ERR("No memory.\n");
307 return NULL;
309 params.buffer = buffer;
310 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag, &params))
312 ERR("wg_parser_stream_get_tag failed unexpectedly.\n");
313 free(buffer);
314 return NULL;
316 return buffer;
319 void wg_parser_stream_seek(wg_parser_stream_t stream, double rate,
320 uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags)
322 struct wg_parser_stream_seek_params params =
324 .stream = stream,
325 .rate = rate,
326 .start_pos = start_pos,
327 .stop_pos = stop_pos,
328 .start_flags = start_flags,
329 .stop_flags = stop_flags,
332 TRACE("stream %#I64x, rate %.16e, start_pos %I64u, stop_pos %I64u, start_flags %#lx, stop_flags %#lx.\n",
333 stream, rate, start_pos, stop_pos, start_flags, stop_flags);
335 WINE_UNIX_CALL(unix_wg_parser_stream_seek, &params);
338 wg_transform_t wg_transform_create(const struct wg_format *input_format,
339 const struct wg_format *output_format, const struct wg_transform_attrs *attrs)
341 struct wg_transform_create_params params =
343 .input_format = input_format,
344 .output_format = output_format,
345 .attrs = attrs,
348 TRACE("input_format %p, output_format %p.\n", input_format, output_format);
350 if (WINE_UNIX_CALL(unix_wg_transform_create, &params))
351 return 0;
353 TRACE("Returning transform %#I64x.\n", params.transform);
354 return params.transform;
357 void wg_transform_destroy(wg_transform_t transform)
359 TRACE("transform %#I64x.\n", transform);
361 WINE_UNIX_CALL(unix_wg_transform_destroy, &transform);
364 HRESULT wg_transform_push_data(wg_transform_t transform, struct wg_sample *sample)
366 struct wg_transform_push_data_params params =
368 .transform = transform,
369 .sample = sample,
371 NTSTATUS status;
373 TRACE("transform %#I64x, sample %p.\n", transform, sample);
375 if ((status = WINE_UNIX_CALL(unix_wg_transform_push_data, &params)))
376 return HRESULT_FROM_NT(status);
378 return params.result;
381 HRESULT wg_transform_read_data(wg_transform_t transform, struct wg_sample *sample,
382 struct wg_format *format)
384 struct wg_transform_read_data_params params =
386 .transform = transform,
387 .sample = sample,
388 .format = format,
390 NTSTATUS status;
392 TRACE("transform %#I64x, sample %p, format %p.\n", transform, sample, format);
394 if ((status = WINE_UNIX_CALL(unix_wg_transform_read_data, &params)))
395 return HRESULT_FROM_NT(status);
397 return params.result;
400 bool wg_transform_get_status(wg_transform_t transform, bool *accepts_input)
402 struct wg_transform_get_status_params params =
404 .transform = transform,
407 TRACE("transform %#I64x, accepts_input %p.\n", transform, accepts_input);
409 if (WINE_UNIX_CALL(unix_wg_transform_get_status, &params))
410 return false;
412 *accepts_input = params.accepts_input;
413 return true;
416 bool wg_transform_set_output_format(wg_transform_t transform, struct wg_format *format)
418 struct wg_transform_set_output_format_params params =
420 .transform = transform,
421 .format = format,
424 TRACE("transform %#I64x, format %p.\n", transform, format);
426 return !WINE_UNIX_CALL(unix_wg_transform_set_output_format, &params);
429 HRESULT wg_transform_drain(wg_transform_t transform)
431 NTSTATUS status;
433 TRACE("transform %#I64x.\n", transform);
435 if ((status = WINE_UNIX_CALL(unix_wg_transform_drain, &transform)))
437 WARN("wg_transform_drain returned status %#lx\n", status);
438 return HRESULT_FROM_NT(status);
441 return S_OK;
444 HRESULT wg_transform_flush(wg_transform_t transform)
446 NTSTATUS status;
448 TRACE("transform %#I64x.\n", transform);
450 if ((status = WINE_UNIX_CALL(unix_wg_transform_flush, &transform)))
452 WARN("wg_transform_flush returned status %#lx\n", status);
453 return HRESULT_FROM_NT(status);
456 return S_OK;
459 #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
461 unsigned int wg_format_get_stride(const struct wg_format *format)
463 const unsigned int width = format->u.video.width;
465 switch (format->u.video.format)
467 case WG_VIDEO_FORMAT_AYUV:
468 return width * 4;
470 case WG_VIDEO_FORMAT_BGRA:
471 case WG_VIDEO_FORMAT_BGRx:
472 return width * 4;
474 case WG_VIDEO_FORMAT_BGR:
475 return ALIGN(width * 3, 4);
477 case WG_VIDEO_FORMAT_UYVY:
478 case WG_VIDEO_FORMAT_YUY2:
479 case WG_VIDEO_FORMAT_YVYU:
480 return ALIGN(width * 2, 4);
482 case WG_VIDEO_FORMAT_RGB15:
483 case WG_VIDEO_FORMAT_RGB16:
484 return ALIGN(width * 2, 4);
486 case WG_VIDEO_FORMAT_I420:
487 case WG_VIDEO_FORMAT_NV12:
488 case WG_VIDEO_FORMAT_YV12:
489 return ALIGN(width, 4); /* Y plane */
491 case WG_VIDEO_FORMAT_UNKNOWN:
492 FIXME("Cannot calculate stride for unknown video format.\n");
495 return 0;
498 bool wg_video_format_is_rgb(enum wg_video_format format)
500 switch (format)
502 case WG_VIDEO_FORMAT_BGRA:
503 case WG_VIDEO_FORMAT_BGRx:
504 case WG_VIDEO_FORMAT_BGR:
505 case WG_VIDEO_FORMAT_RGB15:
506 case WG_VIDEO_FORMAT_RGB16:
507 return true;
509 case WG_VIDEO_FORMAT_AYUV:
510 case WG_VIDEO_FORMAT_I420:
511 case WG_VIDEO_FORMAT_NV12:
512 case WG_VIDEO_FORMAT_UYVY:
513 case WG_VIDEO_FORMAT_YUY2:
514 case WG_VIDEO_FORMAT_YV12:
515 case WG_VIDEO_FORMAT_YVYU:
516 case WG_VIDEO_FORMAT_UNKNOWN:
517 break;
520 return false;
523 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
525 if (reason == DLL_PROCESS_ATTACH)
527 DisableThreadLibraryCalls(instance);
528 __wine_init_unix_call();
530 return TRUE;
533 struct class_factory
535 IClassFactory IClassFactory_iface;
536 HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
539 static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
541 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
544 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
546 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
548 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
550 *out = iface;
551 IClassFactory_AddRef(iface);
552 return S_OK;
555 *out = NULL;
556 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
557 return E_NOINTERFACE;
560 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
562 return 2;
565 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
567 return 1;
570 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
572 struct class_factory *factory = impl_from_IClassFactory(iface);
573 IUnknown *unk;
574 HRESULT hr;
576 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
578 if (outer && !IsEqualGUID(iid, &IID_IUnknown))
579 return E_NOINTERFACE;
581 *out = NULL;
582 if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
584 hr = IUnknown_QueryInterface(unk, iid, out);
585 IUnknown_Release(unk);
587 return hr;
590 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
592 TRACE("iface %p, lock %d.\n", iface, lock);
593 return S_OK;
596 static const IClassFactoryVtbl class_factory_vtbl =
598 class_factory_QueryInterface,
599 class_factory_AddRef,
600 class_factory_Release,
601 class_factory_CreateInstance,
602 class_factory_LockServer,
605 static struct class_factory avi_splitter_cf = {{&class_factory_vtbl}, avi_splitter_create};
606 static struct class_factory decodebin_parser_cf = {{&class_factory_vtbl}, decodebin_parser_create};
607 static struct class_factory mpeg_audio_codec_cf = {{&class_factory_vtbl}, mpeg_audio_codec_create};
608 static struct class_factory mpeg_layer3_decoder_cf = {{&class_factory_vtbl}, mpeg_layer3_decoder_create};
609 static struct class_factory mpeg_splitter_cf = {{&class_factory_vtbl}, mpeg_splitter_create};
610 static struct class_factory wave_parser_cf = {{&class_factory_vtbl}, wave_parser_create};
611 static struct class_factory wma_decoder_cf = {{&class_factory_vtbl}, wma_decoder_create};
612 static struct class_factory wmv_decoder_cf = {{&class_factory_vtbl}, wmv_decoder_create};
613 static struct class_factory resampler_cf = {{&class_factory_vtbl}, resampler_create};
614 static struct class_factory color_convert_cf = {{&class_factory_vtbl}, color_convert_create};
616 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
618 struct class_factory *factory;
619 HRESULT hr;
621 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
623 if (!init_gstreamer())
624 return CLASS_E_CLASSNOTAVAILABLE;
626 if (SUCCEEDED(hr = mfplat_get_class_object(clsid, iid, out)))
627 return hr;
629 if (IsEqualGUID(clsid, &CLSID_AviSplitter))
630 factory = &avi_splitter_cf;
631 else if (IsEqualGUID(clsid, &CLSID_decodebin_parser))
632 factory = &decodebin_parser_cf;
633 else if (IsEqualGUID(clsid, &CLSID_CMpegAudioCodec))
634 factory = &mpeg_audio_codec_cf;
635 else if (IsEqualGUID(clsid, &CLSID_mpeg_layer3_decoder))
636 factory = &mpeg_layer3_decoder_cf;
637 else if (IsEqualGUID(clsid, &CLSID_MPEG1Splitter))
638 factory = &mpeg_splitter_cf;
639 else if (IsEqualGUID(clsid, &CLSID_WAVEParser))
640 factory = &wave_parser_cf;
641 else if (IsEqualGUID(clsid, &CLSID_WMADecMediaObject))
642 factory = &wma_decoder_cf;
643 else if (IsEqualGUID(clsid, &CLSID_WMVDecoderMFT))
644 factory = &wmv_decoder_cf;
645 else if (IsEqualGUID(clsid, &CLSID_CResamplerMediaObject))
646 factory = &resampler_cf;
647 else if (IsEqualGUID(clsid, &CLSID_CColorConvertDMO))
648 factory = &color_convert_cf;
649 else
651 FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
652 return CLASS_E_CLASSNOTAVAILABLE;
655 return IClassFactory_QueryInterface(&factory->IClassFactory_iface, iid, out);
658 static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ctx)
660 HINSTANCE handle;
662 if (WINE_UNIX_CALL(unix_wg_init_gstreamer, NULL))
663 return FALSE;
665 /* Unloading glib is a bad idea.. it installs atexit handlers,
666 * so never unload the dll after loading */
667 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
668 (LPCWSTR)init_gstreamer_proc, &handle);
669 if (!handle)
670 ERR("Failed to pin module.\n");
672 return TRUE;
675 BOOL init_gstreamer(void)
677 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
679 InitOnceExecuteOnce(&once, init_gstreamer_proc, NULL, NULL);
681 return TRUE;
684 static const REGPINTYPES reg_audio_mt = {&MEDIATYPE_Audio, &GUID_NULL};
685 static const REGPINTYPES reg_stream_mt = {&MEDIATYPE_Stream, &GUID_NULL};
686 static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL};
688 static const REGPINTYPES reg_avi_splitter_sink_mt = {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi};
690 static const REGFILTERPINS2 reg_avi_splitter_pins[2] =
693 .nMediaTypes = 1,
694 .lpMediaType = &reg_avi_splitter_sink_mt,
697 .dwFlags = REG_PINFLAG_B_OUTPUT,
698 .nMediaTypes = 1,
699 .lpMediaType = &reg_video_mt,
703 static const REGFILTER2 reg_avi_splitter =
705 .dwVersion = 2,
706 .dwMerit = MERIT_NORMAL,
707 .u.s2.cPins2 = 2,
708 .u.s2.rgPins2 = reg_avi_splitter_pins,
711 static const REGPINTYPES reg_mpeg_audio_codec_sink_mts[3] =
713 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
714 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Payload},
715 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
718 static const REGPINTYPES reg_mpeg_audio_codec_source_mts[1] =
720 {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM},
723 static const REGFILTERPINS2 reg_mpeg_audio_codec_pins[2] =
726 .nMediaTypes = 3,
727 .lpMediaType = reg_mpeg_audio_codec_sink_mts,
730 .dwFlags = REG_PINFLAG_B_OUTPUT,
731 .nMediaTypes = 1,
732 .lpMediaType = reg_mpeg_audio_codec_source_mts,
736 static const REGFILTER2 reg_mpeg_audio_codec =
738 .dwVersion = 2,
739 .dwMerit = 0x03680001,
740 .u.s2.cPins2 = 2,
741 .u.s2.rgPins2 = reg_mpeg_audio_codec_pins,
744 static const REGPINTYPES reg_mpeg_layer3_decoder_sink_mts[1] =
746 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MP3},
749 static const REGPINTYPES reg_mpeg_layer3_decoder_source_mts[1] =
751 {&MEDIATYPE_Audio, &MEDIASUBTYPE_PCM},
754 static const REGFILTERPINS2 reg_mpeg_layer3_decoder_pins[2] =
757 .nMediaTypes = 1,
758 .lpMediaType = reg_mpeg_layer3_decoder_sink_mts,
761 .dwFlags = REG_PINFLAG_B_OUTPUT,
762 .nMediaTypes = 1,
763 .lpMediaType = reg_mpeg_layer3_decoder_source_mts,
767 static const REGFILTER2 reg_mpeg_layer3_decoder =
769 .dwVersion = 2,
770 .dwMerit = 0x00810000,
771 .u.s2.cPins2 = 2,
772 .u.s2.rgPins2 = reg_mpeg_layer3_decoder_pins,
775 static const REGPINTYPES reg_mpeg_splitter_sink_mts[4] =
777 {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
778 {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video},
779 {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
780 {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD},
783 static const REGPINTYPES reg_mpeg_splitter_audio_mts[2] =
785 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
786 {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
789 static const REGPINTYPES reg_mpeg_splitter_video_mts[2] =
791 {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet},
792 {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload},
795 static const REGFILTERPINS2 reg_mpeg_splitter_pins[3] =
798 .nMediaTypes = 4,
799 .lpMediaType = reg_mpeg_splitter_sink_mts,
802 .dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
803 .nMediaTypes = 2,
804 .lpMediaType = reg_mpeg_splitter_audio_mts,
807 .dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
808 .nMediaTypes = 2,
809 .lpMediaType = reg_mpeg_splitter_video_mts,
813 static const REGFILTER2 reg_mpeg_splitter =
815 .dwVersion = 2,
816 .dwMerit = MERIT_NORMAL,
817 .u.s2.cPins2 = 3,
818 .u.s2.rgPins2 = reg_mpeg_splitter_pins,
821 static const REGPINTYPES reg_wave_parser_sink_mts[3] =
823 {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
824 {&MEDIATYPE_Stream, &MEDIASUBTYPE_AU},
825 {&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF},
828 static const REGFILTERPINS2 reg_wave_parser_pins[2] =
831 .nMediaTypes = 3,
832 .lpMediaType = reg_wave_parser_sink_mts,
835 .dwFlags = REG_PINFLAG_B_OUTPUT,
836 .nMediaTypes = 1,
837 .lpMediaType = &reg_audio_mt,
841 static const REGFILTER2 reg_wave_parser =
843 .dwVersion = 2,
844 .dwMerit = MERIT_UNLIKELY,
845 .u.s2.cPins2 = 2,
846 .u.s2.rgPins2 = reg_wave_parser_pins,
849 static const REGFILTERPINS2 reg_decodebin_parser_pins[3] =
852 .nMediaTypes = 1,
853 .lpMediaType = &reg_stream_mt,
856 .dwFlags = REG_PINFLAG_B_OUTPUT,
857 .nMediaTypes = 1,
858 .lpMediaType = &reg_audio_mt,
861 .dwFlags = REG_PINFLAG_B_OUTPUT,
862 .nMediaTypes = 1,
863 .lpMediaType = &reg_video_mt,
867 static const REGFILTER2 reg_decodebin_parser =
869 .dwVersion = 2,
870 .dwMerit = MERIT_PREFERRED,
871 .u.s2.cPins2 = 3,
872 .u.s2.rgPins2 = reg_decodebin_parser_pins,
875 HRESULT WINAPI DllRegisterServer(void)
877 DMO_PARTIAL_MEDIATYPE audio_convert_types[2] =
879 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_PCM},
880 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_IEEE_FLOAT},
882 DMO_PARTIAL_MEDIATYPE wma_decoder_output[2] =
884 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_PCM},
885 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_IEEE_FLOAT},
887 DMO_PARTIAL_MEDIATYPE wma_decoder_input[4] =
889 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_MSAUDIO1},
890 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_WMAUDIO2},
891 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_WMAUDIO3},
892 {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_WMAUDIO_LOSSLESS},
894 DMO_PARTIAL_MEDIATYPE wmv_decoder_output[11] =
896 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YV12},
897 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YUY2},
898 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_UYVY},
899 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YVYU},
900 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV11},
901 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV12},
902 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB32},
903 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB24},
904 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB565},
905 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB555},
906 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB8},
908 DMO_PARTIAL_MEDIATYPE wmv_decoder_input[8] =
910 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV1},
911 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV2},
912 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV3},
913 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMVA},
914 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WVC1},
915 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMVP},
916 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WVP2},
917 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_VC1S},
919 DMO_PARTIAL_MEDIATYPE color_convert_input[20] =
921 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YV12},
922 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YUY2},
923 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_UYVY},
924 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_AYUV},
925 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV12},
926 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB32},
927 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB565},
928 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_I420},
929 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_IYUV},
930 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YVYU},
931 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB24},
932 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB555},
933 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB8},
934 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_V216},
935 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_V410},
936 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV11},
937 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_Y41P},
938 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_Y41T},
939 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_Y42T},
940 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YVU9},
942 DMO_PARTIAL_MEDIATYPE color_convert_output[16] =
944 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YV12},
945 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YUY2},
946 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_UYVY},
947 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_AYUV},
948 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV12},
949 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB32},
950 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB565},
951 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_I420},
952 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_IYUV},
953 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YVYU},
954 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB24},
955 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB555},
956 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB8},
957 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_V216},
958 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_V410},
959 {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV11},
962 IFilterMapper2 *mapper;
963 HRESULT hr;
965 TRACE(".\n");
967 if (FAILED(hr = __wine_register_resources()))
968 return hr;
970 if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
971 &IID_IFilterMapper2, (void **)&mapper)))
972 return hr;
974 IFilterMapper2_RegisterFilter(mapper, &CLSID_AviSplitter, L"AVI Splitter", NULL, NULL, NULL, &reg_avi_splitter);
975 IFilterMapper2_RegisterFilter(mapper, &CLSID_decodebin_parser,
976 L"GStreamer splitter filter", NULL, NULL, NULL, &reg_decodebin_parser);
977 IFilterMapper2_RegisterFilter(mapper, &CLSID_CMpegAudioCodec,
978 L"MPEG Audio Decoder", NULL, NULL, NULL, &reg_mpeg_audio_codec);
979 IFilterMapper2_RegisterFilter(mapper, &CLSID_mpeg_layer3_decoder,
980 L"MPEG Layer-3 Decoder", NULL, NULL, NULL, &reg_mpeg_layer3_decoder);
981 IFilterMapper2_RegisterFilter(mapper, &CLSID_MPEG1Splitter,
982 L"MPEG-I Stream Splitter", NULL, NULL, NULL, &reg_mpeg_splitter);
983 IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, L"Wave Parser", NULL, NULL, NULL, &reg_wave_parser);
985 IFilterMapper2_Release(mapper);
987 if (FAILED(hr = DMORegister(L"WMAudio Decoder DMO", &CLSID_WMADecMediaObject, &DMOCATEGORY_AUDIO_DECODER,
988 0, ARRAY_SIZE(wma_decoder_input), wma_decoder_input, ARRAY_SIZE(wma_decoder_output), wma_decoder_output)))
989 return hr;
990 if (FAILED(hr = DMORegister(L"WMVideo Decoder DMO", &CLSID_WMVDecoderMFT, &DMOCATEGORY_VIDEO_DECODER,
991 0, ARRAY_SIZE(wmv_decoder_input), wmv_decoder_input, ARRAY_SIZE(wmv_decoder_output), wmv_decoder_output)))
992 return hr;
993 if (FAILED(hr = DMORegister(L"Resampler DMO", &CLSID_CResamplerMediaObject, &DMOCATEGORY_AUDIO_EFFECT,
994 0, ARRAY_SIZE(audio_convert_types), audio_convert_types, ARRAY_SIZE(audio_convert_types), audio_convert_types)))
995 return hr;
996 if (FAILED(hr = DMORegister(L"Color Converter DMO", &CLSID_CColorConvertDMO, &DMOCATEGORY_VIDEO_EFFECT,
997 0, ARRAY_SIZE(color_convert_input), color_convert_input, ARRAY_SIZE(color_convert_output), color_convert_output)))
998 return hr;
1000 return mfplat_DllRegisterServer();
1003 HRESULT WINAPI DllUnregisterServer(void)
1005 IFilterMapper2 *mapper;
1006 HRESULT hr;
1008 TRACE(".\n");
1010 if (FAILED(hr = __wine_unregister_resources()))
1011 return hr;
1013 if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
1014 &IID_IFilterMapper2, (void **)&mapper)))
1015 return hr;
1017 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviSplitter);
1018 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_decodebin_parser);
1019 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_CMpegAudioCodec);
1020 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_mpeg_layer3_decoder);
1021 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_MPEG1Splitter);
1022 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_WAVEParser);
1024 IFilterMapper2_Release(mapper);
1026 if (FAILED(hr = DMOUnregister(&CLSID_CColorConvertDMO, &DMOCATEGORY_VIDEO_EFFECT)))
1027 return hr;
1028 if (FAILED(hr = DMOUnregister(&CLSID_CResamplerMediaObject, &DMOCATEGORY_AUDIO_EFFECT)))
1029 return hr;
1030 if (FAILED(hr = DMOUnregister(&CLSID_WMADecMediaObject, &DMOCATEGORY_AUDIO_DECODER)))
1031 return hr;
1032 if (FAILED(hr = DMOUnregister(&CLSID_WMVDecoderMFT, &DMOCATEGORY_VIDEO_DECODER)))
1033 return hr;
1035 return S_OK;