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
26 #define WIN32_NO_STATUS
28 #include "gst_private.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
;
47 if (count
<= *capacity
)
50 max_capacity
= ~(SIZE_T
)0 / size
;
51 if (count
> max_capacity
)
54 new_capacity
= max(4, *capacity
);
55 while (new_capacity
< count
&& new_capacity
<= max_capacity
/ 2)
57 if (new_capacity
< count
)
58 new_capacity
= max_capacity
;
60 if (!(new_elements
= realloc(*elements
, new_capacity
* size
)))
63 *elements
= new_elements
;
64 *capacity
= new_capacity
;
69 struct wg_parser
*wg_parser_create(enum wg_parser_type type
, bool unlimited_buffering
)
71 struct wg_parser_create_params params
=
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
, ¶ms
))
84 TRACE("Returning parser %p.\n", 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
=
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
, ¶ms
);
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
=
123 TRACE("parser %p, offset %p, size %p.\n", parser
, offset
, size
);
125 if (WINE_UNIX_CALL(unix_wg_parser_get_next_read_offset
, ¶ms
))
127 *offset
= params
.offset
;
132 void wg_parser_push_data(struct wg_parser
*parser
, const void *data
, uint32_t size
)
134 struct wg_parser_push_data_params params
=
141 TRACE("parser %p, data %p, size %u.\n", parser
, data
, size
);
143 WINE_UNIX_CALL(unix_wg_parser_push_data
, ¶ms
);
146 uint32_t wg_parser_get_stream_count(struct wg_parser
*parser
)
148 struct wg_parser_get_stream_count_params params
=
153 TRACE("parser %p.\n", parser
);
155 WINE_UNIX_CALL(unix_wg_parser_get_stream_count
, ¶ms
);
159 struct wg_parser_stream
*wg_parser_get_stream(struct wg_parser
*parser
, uint32_t index
)
161 struct wg_parser_get_stream_params params
=
167 TRACE("parser %p, index %u.\n", parser
, index
);
169 WINE_UNIX_CALL(unix_wg_parser_get_stream
, ¶ms
);
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
=
183 TRACE("stream %p, format %p.\n", stream
, format
);
185 WINE_UNIX_CALL(unix_wg_parser_stream_get_preferred_format
, ¶ms
);
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
=
196 TRACE("stream %p, format %p.\n", stream
, format
);
198 WINE_UNIX_CALL(unix_wg_parser_stream_get_codec_format
, ¶ms
);
201 void wg_parser_stream_enable(struct wg_parser_stream
*stream
, const struct wg_format
*format
)
203 struct wg_parser_stream_enable_params params
=
209 TRACE("stream %p, format %p.\n", stream
, format
);
211 WINE_UNIX_CALL(unix_wg_parser_stream_enable
, ¶ms
);
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
=
231 TRACE("parser %p, stream %p, buffer %p.\n", parser
, stream
, buffer
);
233 return !WINE_UNIX_CALL(unix_wg_parser_stream_get_buffer
, ¶ms
);
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
=
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
, ¶ms
);
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
=
265 .underflow
= underflow
,
266 .proportion
= proportion
,
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
, ¶ms
);
277 uint64_t wg_parser_stream_get_duration(struct wg_parser_stream
*stream
)
279 struct wg_parser_stream_get_duration_params params
=
284 TRACE("stream %p.\n", stream
);
286 WINE_UNIX_CALL(unix_wg_parser_stream_get_duration
, ¶ms
);
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
)
295 struct wg_parser_stream_get_tag_params params
=
303 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag
, ¶ms
) != STATUS_BUFFER_TOO_SMALL
)
305 if (!(buffer
= malloc(size
)))
310 params
.buffer
= buffer
;
311 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag
, ¶ms
))
313 ERR("wg_parser_stream_get_tag failed unexpectedly.\n");
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
=
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
, ¶ms
);
339 struct wg_transform
*wg_transform_create(const struct wg_format
*input_format
,
340 const struct wg_format
*output_format
, const struct wg_transform_attrs
*attrs
)
342 struct wg_transform_create_params params
=
344 .input_format
= input_format
,
345 .output_format
= output_format
,
349 TRACE("input_format %p, output_format %p.\n", input_format
, output_format
);
351 if (WINE_UNIX_CALL(unix_wg_transform_create
, ¶ms
))
354 TRACE("Returning transform %p.\n", params
.transform
);
355 return params
.transform
;
358 void wg_transform_destroy(struct wg_transform
*transform
)
360 TRACE("transform %p.\n", transform
);
362 WINE_UNIX_CALL(unix_wg_transform_destroy
, transform
);
365 HRESULT
wg_transform_push_data(struct wg_transform
*transform
, struct wg_sample
*sample
)
367 struct wg_transform_push_data_params params
=
369 .transform
= transform
,
374 TRACE("transform %p, sample %p.\n", transform
, sample
);
376 if ((status
= WINE_UNIX_CALL(unix_wg_transform_push_data
, ¶ms
)))
377 return HRESULT_FROM_NT(status
);
379 return params
.result
;
382 HRESULT
wg_transform_read_data(struct wg_transform
*transform
, struct wg_sample
*sample
,
383 struct wg_format
*format
)
385 struct wg_transform_read_data_params params
=
387 .transform
= transform
,
393 TRACE("transform %p, sample %p, format %p.\n", transform
, sample
, format
);
395 if ((status
= WINE_UNIX_CALL(unix_wg_transform_read_data
, ¶ms
)))
396 return HRESULT_FROM_NT(status
);
398 return params
.result
;
401 bool wg_transform_get_status(struct wg_transform
*transform
, bool *accepts_input
)
403 struct wg_transform_get_status_params params
=
405 .transform
= transform
,
408 TRACE("transform %p, accepts_input %p.\n", transform
, accepts_input
);
410 if (WINE_UNIX_CALL(unix_wg_transform_get_status
, ¶ms
))
413 *accepts_input
= params
.accepts_input
;
417 bool wg_transform_set_output_format(struct wg_transform
*transform
, struct wg_format
*format
)
419 struct wg_transform_set_output_format_params params
=
421 .transform
= transform
,
425 TRACE("transform %p, format %p.\n", transform
, format
);
427 return !WINE_UNIX_CALL(unix_wg_transform_set_output_format
, ¶ms
);
430 HRESULT
wg_transform_drain(struct wg_transform
*transform
)
434 TRACE("transform %p.\n", transform
);
436 if ((status
= WINE_UNIX_CALL(unix_wg_transform_drain
, transform
)))
438 WARN("wg_transform_drain returned status %#lx\n", status
);
439 return HRESULT_FROM_NT(status
);
445 HRESULT
wg_transform_flush(struct wg_transform
*transform
)
449 TRACE("transform %p.\n", transform
);
451 if ((status
= WINE_UNIX_CALL(unix_wg_transform_flush
, transform
)))
453 WARN("wg_transform_flush returned status %#lx\n", status
);
454 return HRESULT_FROM_NT(status
);
460 #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
462 unsigned int wg_format_get_stride(const struct wg_format
*format
)
464 const unsigned int width
= format
->u
.video
.width
;
466 switch (format
->u
.video
.format
)
468 case WG_VIDEO_FORMAT_AYUV
:
471 case WG_VIDEO_FORMAT_BGRA
:
472 case WG_VIDEO_FORMAT_BGRx
:
475 case WG_VIDEO_FORMAT_BGR
:
476 return ALIGN(width
* 3, 4);
478 case WG_VIDEO_FORMAT_UYVY
:
479 case WG_VIDEO_FORMAT_YUY2
:
480 case WG_VIDEO_FORMAT_YVYU
:
481 return ALIGN(width
* 2, 4);
483 case WG_VIDEO_FORMAT_RGB15
:
484 case WG_VIDEO_FORMAT_RGB16
:
485 return ALIGN(width
* 2, 4);
487 case WG_VIDEO_FORMAT_I420
:
488 case WG_VIDEO_FORMAT_NV12
:
489 case WG_VIDEO_FORMAT_YV12
:
490 return ALIGN(width
, 4); /* Y plane */
492 case WG_VIDEO_FORMAT_UNKNOWN
:
493 FIXME("Cannot calculate stride for unknown video format.\n");
499 bool wg_video_format_is_rgb(enum wg_video_format format
)
503 case WG_VIDEO_FORMAT_BGRA
:
504 case WG_VIDEO_FORMAT_BGRx
:
505 case WG_VIDEO_FORMAT_BGR
:
506 case WG_VIDEO_FORMAT_RGB15
:
507 case WG_VIDEO_FORMAT_RGB16
:
510 case WG_VIDEO_FORMAT_AYUV
:
511 case WG_VIDEO_FORMAT_I420
:
512 case WG_VIDEO_FORMAT_NV12
:
513 case WG_VIDEO_FORMAT_UYVY
:
514 case WG_VIDEO_FORMAT_YUY2
:
515 case WG_VIDEO_FORMAT_YV12
:
516 case WG_VIDEO_FORMAT_YVYU
:
517 case WG_VIDEO_FORMAT_UNKNOWN
:
524 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, void *reserved
)
526 if (reason
== DLL_PROCESS_ATTACH
)
528 DisableThreadLibraryCalls(instance
);
529 __wine_init_unix_call();
536 IClassFactory IClassFactory_iface
;
537 HRESULT (*create_instance
)(IUnknown
*outer
, IUnknown
**out
);
540 static inline struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
542 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
545 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID iid
, void **out
)
547 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
549 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IClassFactory
))
552 IClassFactory_AddRef(iface
);
557 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
558 return E_NOINTERFACE
;
561 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
566 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
571 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID iid
, void **out
)
573 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
577 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface
, outer
, debugstr_guid(iid
), out
);
579 if (outer
&& !IsEqualGUID(iid
, &IID_IUnknown
))
580 return E_NOINTERFACE
;
583 if (SUCCEEDED(hr
= factory
->create_instance(outer
, &unk
)))
585 hr
= IUnknown_QueryInterface(unk
, iid
, out
);
586 IUnknown_Release(unk
);
591 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL lock
)
593 TRACE("iface %p, lock %d.\n", iface
, lock
);
597 static const IClassFactoryVtbl class_factory_vtbl
=
599 class_factory_QueryInterface
,
600 class_factory_AddRef
,
601 class_factory_Release
,
602 class_factory_CreateInstance
,
603 class_factory_LockServer
,
606 static struct class_factory avi_splitter_cf
= {{&class_factory_vtbl
}, avi_splitter_create
};
607 static struct class_factory decodebin_parser_cf
= {{&class_factory_vtbl
}, decodebin_parser_create
};
608 static struct class_factory mpeg_audio_codec_cf
= {{&class_factory_vtbl
}, mpeg_audio_codec_create
};
609 static struct class_factory mpeg_layer3_decoder_cf
= {{&class_factory_vtbl
}, mpeg_layer3_decoder_create
};
610 static struct class_factory mpeg_splitter_cf
= {{&class_factory_vtbl
}, mpeg_splitter_create
};
611 static struct class_factory wave_parser_cf
= {{&class_factory_vtbl
}, wave_parser_create
};
612 static struct class_factory wma_decoder_cf
= {{&class_factory_vtbl
}, wma_decoder_create
};
613 static struct class_factory wmv_decoder_cf
= {{&class_factory_vtbl
}, wmv_decoder_create
};
614 static struct class_factory resampler_cf
= {{&class_factory_vtbl
}, resampler_create
};
615 static struct class_factory color_convert_cf
= {{&class_factory_vtbl
}, color_convert_create
};
617 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID iid
, void **out
)
619 struct class_factory
*factory
;
622 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid
), debugstr_guid(iid
), out
);
624 if (!init_gstreamer())
625 return CLASS_E_CLASSNOTAVAILABLE
;
627 if (SUCCEEDED(hr
= mfplat_get_class_object(clsid
, iid
, out
)))
630 if (IsEqualGUID(clsid
, &CLSID_AviSplitter
))
631 factory
= &avi_splitter_cf
;
632 else if (IsEqualGUID(clsid
, &CLSID_decodebin_parser
))
633 factory
= &decodebin_parser_cf
;
634 else if (IsEqualGUID(clsid
, &CLSID_CMpegAudioCodec
))
635 factory
= &mpeg_audio_codec_cf
;
636 else if (IsEqualGUID(clsid
, &CLSID_mpeg_layer3_decoder
))
637 factory
= &mpeg_layer3_decoder_cf
;
638 else if (IsEqualGUID(clsid
, &CLSID_MPEG1Splitter
))
639 factory
= &mpeg_splitter_cf
;
640 else if (IsEqualGUID(clsid
, &CLSID_WAVEParser
))
641 factory
= &wave_parser_cf
;
642 else if (IsEqualGUID(clsid
, &CLSID_WMADecMediaObject
))
643 factory
= &wma_decoder_cf
;
644 else if (IsEqualGUID(clsid
, &CLSID_WMVDecoderMFT
))
645 factory
= &wmv_decoder_cf
;
646 else if (IsEqualGUID(clsid
, &CLSID_CResamplerMediaObject
))
647 factory
= &resampler_cf
;
648 else if (IsEqualGUID(clsid
, &CLSID_CColorConvertDMO
))
649 factory
= &color_convert_cf
;
652 FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid
));
653 return CLASS_E_CLASSNOTAVAILABLE
;
656 return IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, iid
, out
);
659 static BOOL CALLBACK
init_gstreamer_proc(INIT_ONCE
*once
, void *param
, void **ctx
)
663 if (WINE_UNIX_CALL(unix_wg_init_gstreamer
, NULL
))
666 /* Unloading glib is a bad idea.. it installs atexit handlers,
667 * so never unload the dll after loading */
668 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
| GET_MODULE_HANDLE_EX_FLAG_PIN
,
669 (LPCWSTR
)init_gstreamer_proc
, &handle
);
671 ERR("Failed to pin module.\n");
676 BOOL
init_gstreamer(void)
678 static INIT_ONCE once
= INIT_ONCE_STATIC_INIT
;
680 InitOnceExecuteOnce(&once
, init_gstreamer_proc
, NULL
, NULL
);
685 static const REGPINTYPES reg_audio_mt
= {&MEDIATYPE_Audio
, &GUID_NULL
};
686 static const REGPINTYPES reg_stream_mt
= {&MEDIATYPE_Stream
, &GUID_NULL
};
687 static const REGPINTYPES reg_video_mt
= {&MEDIATYPE_Video
, &GUID_NULL
};
689 static const REGPINTYPES reg_avi_splitter_sink_mt
= {&MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
};
691 static const REGFILTERPINS2 reg_avi_splitter_pins
[2] =
695 .lpMediaType
= ®_avi_splitter_sink_mt
,
698 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
700 .lpMediaType
= ®_video_mt
,
704 static const REGFILTER2 reg_avi_splitter
=
707 .dwMerit
= MERIT_NORMAL
,
709 .u
.s2
.rgPins2
= reg_avi_splitter_pins
,
712 static const REGPINTYPES reg_mpeg_audio_codec_sink_mts
[3] =
714 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
715 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Payload
},
716 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
719 static const REGPINTYPES reg_mpeg_audio_codec_source_mts
[1] =
721 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
724 static const REGFILTERPINS2 reg_mpeg_audio_codec_pins
[2] =
728 .lpMediaType
= reg_mpeg_audio_codec_sink_mts
,
731 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
733 .lpMediaType
= reg_mpeg_audio_codec_source_mts
,
737 static const REGFILTER2 reg_mpeg_audio_codec
=
740 .dwMerit
= 0x03680001,
742 .u
.s2
.rgPins2
= reg_mpeg_audio_codec_pins
,
745 static const REGPINTYPES reg_mpeg_layer3_decoder_sink_mts
[1] =
747 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MP3
},
750 static const REGPINTYPES reg_mpeg_layer3_decoder_source_mts
[1] =
752 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
755 static const REGFILTERPINS2 reg_mpeg_layer3_decoder_pins
[2] =
759 .lpMediaType
= reg_mpeg_layer3_decoder_sink_mts
,
762 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
764 .lpMediaType
= reg_mpeg_layer3_decoder_source_mts
,
768 static const REGFILTER2 reg_mpeg_layer3_decoder
=
771 .dwMerit
= 0x00810000,
773 .u
.s2
.rgPins2
= reg_mpeg_layer3_decoder_pins
,
776 static const REGPINTYPES reg_mpeg_splitter_sink_mts
[4] =
778 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
779 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
780 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
781 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
784 static const REGPINTYPES reg_mpeg_splitter_audio_mts
[2] =
786 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
787 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
790 static const REGPINTYPES reg_mpeg_splitter_video_mts
[2] =
792 {&MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
793 {&MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
796 static const REGFILTERPINS2 reg_mpeg_splitter_pins
[3] =
800 .lpMediaType
= reg_mpeg_splitter_sink_mts
,
803 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
805 .lpMediaType
= reg_mpeg_splitter_audio_mts
,
808 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
810 .lpMediaType
= reg_mpeg_splitter_video_mts
,
814 static const REGFILTER2 reg_mpeg_splitter
=
817 .dwMerit
= MERIT_NORMAL
,
819 .u
.s2
.rgPins2
= reg_mpeg_splitter_pins
,
822 static const REGPINTYPES reg_wave_parser_sink_mts
[3] =
824 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
825 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
826 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
829 static const REGFILTERPINS2 reg_wave_parser_pins
[2] =
833 .lpMediaType
= reg_wave_parser_sink_mts
,
836 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
838 .lpMediaType
= ®_audio_mt
,
842 static const REGFILTER2 reg_wave_parser
=
845 .dwMerit
= MERIT_UNLIKELY
,
847 .u
.s2
.rgPins2
= reg_wave_parser_pins
,
850 static const REGFILTERPINS2 reg_decodebin_parser_pins
[3] =
854 .lpMediaType
= ®_stream_mt
,
857 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
859 .lpMediaType
= ®_audio_mt
,
862 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
864 .lpMediaType
= ®_video_mt
,
868 static const REGFILTER2 reg_decodebin_parser
=
871 .dwMerit
= MERIT_PREFERRED
,
873 .u
.s2
.rgPins2
= reg_decodebin_parser_pins
,
876 HRESULT WINAPI
DllRegisterServer(void)
878 DMO_PARTIAL_MEDIATYPE audio_convert_types
[2] =
880 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_PCM
},
881 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_IEEE_FLOAT
},
883 DMO_PARTIAL_MEDIATYPE wma_decoder_output
[2] =
885 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_PCM
},
886 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_IEEE_FLOAT
},
888 DMO_PARTIAL_MEDIATYPE wma_decoder_input
[4] =
890 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_MSAUDIO1
},
891 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_WMAUDIO2
},
892 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_WMAUDIO3
},
893 {.type
= MEDIATYPE_Audio
, .subtype
= MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
895 DMO_PARTIAL_MEDIATYPE wmv_decoder_output
[11] =
897 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YV12
},
898 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YUY2
},
899 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_UYVY
},
900 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YVYU
},
901 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV11
},
902 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV12
},
903 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB32
},
904 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB24
},
905 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB565
},
906 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB555
},
907 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB8
},
909 DMO_PARTIAL_MEDIATYPE wmv_decoder_input
[8] =
911 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WMV1
},
912 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WMV2
},
913 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WMV3
},
914 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WMVA
},
915 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WVC1
},
916 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WMVP
},
917 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_WVP2
},
918 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_VC1S
},
920 DMO_PARTIAL_MEDIATYPE color_convert_input
[20] =
922 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YV12
},
923 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YUY2
},
924 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_UYVY
},
925 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_AYUV
},
926 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV12
},
927 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB32
},
928 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB565
},
929 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_I420
},
930 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_IYUV
},
931 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YVYU
},
932 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB24
},
933 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB555
},
934 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB8
},
935 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_V216
},
936 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_V410
},
937 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV11
},
938 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_Y41P
},
939 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_Y41T
},
940 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_Y42T
},
941 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YVU9
},
943 DMO_PARTIAL_MEDIATYPE color_convert_output
[16] =
945 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YV12
},
946 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YUY2
},
947 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_UYVY
},
948 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_AYUV
},
949 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV12
},
950 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB32
},
951 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB565
},
952 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_I420
},
953 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_IYUV
},
954 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_YVYU
},
955 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB24
},
956 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB555
},
957 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_RGB8
},
958 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_V216
},
959 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_V410
},
960 {.type
= MEDIATYPE_Video
, .subtype
= MEDIASUBTYPE_NV11
},
963 IFilterMapper2
*mapper
;
968 if (FAILED(hr
= __wine_register_resources()))
971 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
972 &IID_IFilterMapper2
, (void **)&mapper
)))
975 IFilterMapper2_RegisterFilter(mapper
, &CLSID_AviSplitter
, L
"AVI Splitter", NULL
, NULL
, NULL
, ®_avi_splitter
);
976 IFilterMapper2_RegisterFilter(mapper
, &CLSID_decodebin_parser
,
977 L
"GStreamer splitter filter", NULL
, NULL
, NULL
, ®_decodebin_parser
);
978 IFilterMapper2_RegisterFilter(mapper
, &CLSID_CMpegAudioCodec
,
979 L
"MPEG Audio Decoder", NULL
, NULL
, NULL
, ®_mpeg_audio_codec
);
980 IFilterMapper2_RegisterFilter(mapper
, &CLSID_mpeg_layer3_decoder
,
981 L
"MPEG Layer-3 Decoder", NULL
, NULL
, NULL
, ®_mpeg_layer3_decoder
);
982 IFilterMapper2_RegisterFilter(mapper
, &CLSID_MPEG1Splitter
,
983 L
"MPEG-I Stream Splitter", NULL
, NULL
, NULL
, ®_mpeg_splitter
);
984 IFilterMapper2_RegisterFilter(mapper
, &CLSID_WAVEParser
, L
"Wave Parser", NULL
, NULL
, NULL
, ®_wave_parser
);
986 IFilterMapper2_Release(mapper
);
988 if (FAILED(hr
= DMORegister(L
"WMAudio Decoder DMO", &CLSID_WMADecMediaObject
, &DMOCATEGORY_AUDIO_DECODER
,
989 0, ARRAY_SIZE(wma_decoder_input
), wma_decoder_input
, ARRAY_SIZE(wma_decoder_output
), wma_decoder_output
)))
991 if (FAILED(hr
= DMORegister(L
"WMVideo Decoder DMO", &CLSID_WMVDecoderMFT
, &DMOCATEGORY_VIDEO_DECODER
,
992 0, ARRAY_SIZE(wmv_decoder_input
), wmv_decoder_input
, ARRAY_SIZE(wmv_decoder_output
), wmv_decoder_output
)))
994 if (FAILED(hr
= DMORegister(L
"Resampler DMO", &CLSID_CResamplerMediaObject
, &DMOCATEGORY_AUDIO_EFFECT
,
995 0, ARRAY_SIZE(audio_convert_types
), audio_convert_types
, ARRAY_SIZE(audio_convert_types
), audio_convert_types
)))
997 if (FAILED(hr
= DMORegister(L
"Color Converter DMO", &CLSID_CColorConvertDMO
, &DMOCATEGORY_VIDEO_EFFECT
,
998 0, ARRAY_SIZE(color_convert_input
), color_convert_input
, ARRAY_SIZE(color_convert_output
), color_convert_output
)))
1001 return mfplat_DllRegisterServer();
1004 HRESULT WINAPI
DllUnregisterServer(void)
1006 IFilterMapper2
*mapper
;
1011 if (FAILED(hr
= __wine_unregister_resources()))
1014 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
1015 &IID_IFilterMapper2
, (void **)&mapper
)))
1018 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_AviSplitter
);
1019 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_decodebin_parser
);
1020 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_CMpegAudioCodec
);
1021 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_mpeg_layer3_decoder
);
1022 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_MPEG1Splitter
);
1023 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_WAVEParser
);
1025 IFilterMapper2_Release(mapper
);
1027 if (FAILED(hr
= DMOUnregister(&CLSID_CColorConvertDMO
, &DMOCATEGORY_VIDEO_EFFECT
)))
1029 if (FAILED(hr
= DMOUnregister(&CLSID_CResamplerMediaObject
, &DMOCATEGORY_AUDIO_EFFECT
)))
1031 if (FAILED(hr
= DMOUnregister(&CLSID_WMADecMediaObject
, &DMOCATEGORY_AUDIO_DECODER
)))
1033 if (FAILED(hr
= DMOUnregister(&CLSID_WMVDecoderMFT
, &DMOCATEGORY_VIDEO_DECODER
)))