winegstreamer: Implement MFT_MESSAGE_COMMAND_FLUSH for the H264 decoder.
[wine.git] / dlls / winegstreamer / main.c
blobbd4f7108387b20d33e63c8ea118f33b3ca02d9bc
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 struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buffering)
71 struct wg_parser_create_params params =
73 .type = type,
74 .unlimited_buffering = unlimited_buffering,
75 .err_on = ERR_ON(quartz),
76 .warn_on = WARN_ON(quartz),
79 TRACE("type %#x, unlimited_buffering %d.\n", type, unlimited_buffering);
81 if (WINE_UNIX_CALL(unix_wg_parser_create, &params))
82 return NULL;
84 TRACE("Returning parser %p.\n", params.parser);
86 return params.parser;
89 void wg_parser_destroy(struct wg_parser *parser)
91 TRACE("parser %p.\n", parser);
93 WINE_UNIX_CALL(unix_wg_parser_destroy, parser);
96 HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size)
98 struct wg_parser_connect_params params =
100 .parser = parser,
101 .file_size = file_size,
104 TRACE("parser %p, file_size %I64u.\n", parser, file_size);
106 return WINE_UNIX_CALL(unix_wg_parser_connect, &params);
109 void wg_parser_disconnect(struct wg_parser *parser)
111 TRACE("parser %p.\n", parser);
113 WINE_UNIX_CALL(unix_wg_parser_disconnect, parser);
116 bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size)
118 struct wg_parser_get_next_read_offset_params params =
120 .parser = parser,
123 TRACE("parser %p, offset %p, size %p.\n", parser, offset, size);
125 if (WINE_UNIX_CALL(unix_wg_parser_get_next_read_offset, &params))
126 return false;
127 *offset = params.offset;
128 *size = params.size;
129 return true;
132 void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size)
134 struct wg_parser_push_data_params params =
136 .parser = parser,
137 .data = data,
138 .size = size,
141 TRACE("parser %p, data %p, size %u.\n", parser, data, size);
143 WINE_UNIX_CALL(unix_wg_parser_push_data, &params);
146 uint32_t wg_parser_get_stream_count(struct wg_parser *parser)
148 struct wg_parser_get_stream_count_params params =
150 .parser = parser,
153 TRACE("parser %p.\n", parser);
155 WINE_UNIX_CALL(unix_wg_parser_get_stream_count, &params);
156 return params.count;
159 struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index)
161 struct wg_parser_get_stream_params params =
163 .parser = parser,
164 .index = index,
167 TRACE("parser %p, index %u.\n", parser, index);
169 WINE_UNIX_CALL(unix_wg_parser_get_stream, &params);
171 TRACE("Returning stream %p.\n", params.stream);
172 return params.stream;
175 void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format)
177 struct wg_parser_stream_get_preferred_format_params params =
179 .stream = stream,
180 .format = format,
183 TRACE("stream %p, format %p.\n", stream, format);
185 WINE_UNIX_CALL(unix_wg_parser_stream_get_preferred_format, &params);
188 void wg_parser_stream_get_codec_format(struct wg_parser_stream *stream, struct wg_format *format)
190 struct wg_parser_stream_get_codec_format_params params =
192 .stream = stream,
193 .format = format,
196 TRACE("stream %p, format %p.\n", stream, format);
198 WINE_UNIX_CALL(unix_wg_parser_stream_get_codec_format, &params);
201 void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format)
203 struct wg_parser_stream_enable_params params =
205 .stream = stream,
206 .format = format,
209 TRACE("stream %p, format %p.\n", stream, format);
211 WINE_UNIX_CALL(unix_wg_parser_stream_enable, &params);
214 void wg_parser_stream_disable(struct wg_parser_stream *stream)
216 TRACE("stream %p.\n", stream);
218 WINE_UNIX_CALL(unix_wg_parser_stream_disable, stream);
221 bool wg_parser_stream_get_buffer(struct wg_parser *parser, struct wg_parser_stream *stream,
222 struct wg_parser_buffer *buffer)
224 struct wg_parser_stream_get_buffer_params params =
226 .parser = parser,
227 .stream = stream,
228 .buffer = buffer,
231 TRACE("parser %p, stream %p, buffer %p.\n", parser, stream, buffer);
233 return !WINE_UNIX_CALL(unix_wg_parser_stream_get_buffer, &params);
236 bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
237 void *data, uint32_t offset, uint32_t size)
239 struct wg_parser_stream_copy_buffer_params params =
241 .stream = stream,
242 .data = data,
243 .offset = offset,
244 .size = size,
247 TRACE("stream %p, data %p, offset %u, size %u.\n", stream, data, offset, size);
249 return !WINE_UNIX_CALL(unix_wg_parser_stream_copy_buffer, &params);
252 void wg_parser_stream_release_buffer(struct wg_parser_stream *stream)
254 TRACE("stream %p.\n", stream);
256 WINE_UNIX_CALL(unix_wg_parser_stream_release_buffer, stream);
259 void wg_parser_stream_notify_qos(struct wg_parser_stream *stream,
260 bool underflow, double proportion, int64_t diff, uint64_t timestamp)
262 struct wg_parser_stream_notify_qos_params params =
264 .stream = stream,
265 .underflow = underflow,
266 .proportion = proportion,
267 .diff = diff,
268 .timestamp = timestamp,
271 TRACE("stream %p, underflow %d, proportion %.16e, diff %I64d, timestamp %I64u.\n",
272 stream, underflow, proportion, diff, timestamp);
274 WINE_UNIX_CALL(unix_wg_parser_stream_notify_qos, &params);
277 uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream)
279 struct wg_parser_stream_get_duration_params params =
281 .stream = stream,
284 TRACE("stream %p.\n", stream);
286 WINE_UNIX_CALL(unix_wg_parser_stream_get_duration, &params);
288 TRACE("Returning duration %I64u.\n", params.duration);
289 return params.duration;
292 char *wg_parser_stream_get_tag(struct wg_parser_stream *stream, enum wg_parser_tag tag)
294 uint32_t size = 0;
295 struct wg_parser_stream_get_tag_params params =
297 .stream = stream,
298 .tag = tag,
299 .size = &size,
301 char *buffer;
303 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag, &params) != STATUS_BUFFER_TOO_SMALL)
304 return NULL;
305 if (!(buffer = malloc(size)))
307 ERR("No memory.\n");
308 return NULL;
310 params.buffer = buffer;
311 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag, &params))
313 ERR("wg_parser_stream_get_tag failed unexpectedly.\n");
314 free(buffer);
315 return NULL;
317 return buffer;
320 void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate,
321 uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags)
323 struct wg_parser_stream_seek_params params =
325 .stream = stream,
326 .rate = rate,
327 .start_pos = start_pos,
328 .stop_pos = stop_pos,
329 .start_flags = start_flags,
330 .stop_flags = stop_flags,
333 TRACE("stream %p, rate %.16e, start_pos %I64u, stop_pos %I64u, start_flags %#lx, stop_flags %#lx.\n",
334 stream, rate, start_pos, stop_pos, start_flags, stop_flags);
336 WINE_UNIX_CALL(unix_wg_parser_stream_seek, &params);
339 struct wg_transform *wg_transform_create(const struct wg_format *input_format,
340 const struct wg_format *output_format)
342 struct wg_transform_create_params params =
344 .input_format = input_format,
345 .output_format = output_format,
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 NULL;
353 TRACE("Returning transform %p.\n", params.transform);
354 return params.transform;
357 void wg_transform_destroy(struct wg_transform *transform)
359 TRACE("transform %p.\n", transform);
361 WINE_UNIX_CALL(unix_wg_transform_destroy, transform);
364 HRESULT wg_transform_push_data(struct wg_transform *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 %p, 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(struct wg_transform *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 %p, 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(struct wg_transform *transform, bool *accepts_input)
402 struct wg_transform_get_status_params params =
404 .transform = transform,
407 TRACE("transform %p, 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(struct wg_transform *transform, struct wg_format *format)
418 struct wg_transform_set_output_format_params params =
420 .transform = transform,
421 .format = format,
424 TRACE("transform %p, format %p.\n", transform, format);
426 return !WINE_UNIX_CALL(unix_wg_transform_set_output_format, &params);
429 HRESULT wg_transform_drain(struct wg_transform *transform)
431 NTSTATUS status;
433 TRACE("transform %p.\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(struct wg_transform *transform)
446 NTSTATUS status;
448 TRACE("transform %p.\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;