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 wg_parser_t
wg_parser_create(enum wg_parser_type type
)
71 struct wg_parser_create_params params
=
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
, ¶ms
))
83 TRACE("Returning parser %#I64x.\n", 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
=
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
, ¶ms
);
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
=
122 TRACE("parser %#I64x, offset %p, size %p.\n", parser
, offset
, size
);
124 if (WINE_UNIX_CALL(unix_wg_parser_get_next_read_offset
, ¶ms
))
126 *offset
= params
.offset
;
131 void wg_parser_push_data(wg_parser_t parser
, const void *data
, uint32_t size
)
133 struct wg_parser_push_data_params params
=
140 TRACE("parser %#I64x, data %p, size %u.\n", parser
, data
, size
);
142 WINE_UNIX_CALL(unix_wg_parser_push_data
, ¶ms
);
145 uint32_t wg_parser_get_stream_count(wg_parser_t parser
)
147 struct wg_parser_get_stream_count_params params
=
152 TRACE("parser %#I64x.\n", parser
);
154 WINE_UNIX_CALL(unix_wg_parser_get_stream_count
, ¶ms
);
158 wg_parser_stream_t
wg_parser_get_stream(wg_parser_t parser
, uint32_t index
)
160 struct wg_parser_get_stream_params params
=
166 TRACE("parser %#I64x, index %u.\n", parser
, index
);
168 WINE_UNIX_CALL(unix_wg_parser_get_stream
, ¶ms
);
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
=
182 TRACE("stream %#I64x, format %p.\n", stream
, format
);
184 WINE_UNIX_CALL(unix_wg_parser_stream_get_preferred_format
, ¶ms
);
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
=
195 TRACE("stream %#I64x, format %p.\n", stream
, format
);
197 WINE_UNIX_CALL(unix_wg_parser_stream_get_codec_format
, ¶ms
);
200 void wg_parser_stream_enable(wg_parser_stream_t stream
, const struct wg_format
*format
)
202 struct wg_parser_stream_enable_params params
=
208 TRACE("stream %#I64x, format %p.\n", stream
, format
);
210 WINE_UNIX_CALL(unix_wg_parser_stream_enable
, ¶ms
);
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
=
230 TRACE("parser %#I64x, stream %#I64x, buffer %p.\n", parser
, stream
, buffer
);
232 return !WINE_UNIX_CALL(unix_wg_parser_stream_get_buffer
, ¶ms
);
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
=
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
, ¶ms
);
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
=
264 .underflow
= underflow
,
265 .proportion
= proportion
,
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
, ¶ms
);
276 uint64_t wg_parser_stream_get_duration(wg_parser_stream_t stream
)
278 struct wg_parser_stream_get_duration_params params
=
283 TRACE("stream %#I64x.\n", stream
);
285 WINE_UNIX_CALL(unix_wg_parser_stream_get_duration
, ¶ms
);
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
)
294 struct wg_parser_stream_get_tag_params params
=
302 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag
, ¶ms
) != STATUS_BUFFER_TOO_SMALL
)
304 if (!(buffer
= malloc(size
)))
309 params
.buffer
= buffer
;
310 if (WINE_UNIX_CALL(unix_wg_parser_stream_get_tag
, ¶ms
))
312 ERR("wg_parser_stream_get_tag failed unexpectedly.\n");
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
=
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
, ¶ms
);
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
,
348 TRACE("input_format %p, output_format %p.\n", input_format
, output_format
);
350 if (WINE_UNIX_CALL(unix_wg_transform_create
, ¶ms
))
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
,
373 TRACE("transform %#I64x, sample %p.\n", transform
, sample
);
375 if ((status
= WINE_UNIX_CALL(unix_wg_transform_push_data
, ¶ms
)))
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
,
392 TRACE("transform %#I64x, sample %p, format %p.\n", transform
, sample
, format
);
394 if ((status
= WINE_UNIX_CALL(unix_wg_transform_read_data
, ¶ms
)))
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
, ¶ms
))
412 *accepts_input
= params
.accepts_input
;
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
,
424 TRACE("transform %#I64x, format %p.\n", transform
, format
);
426 return !WINE_UNIX_CALL(unix_wg_transform_set_output_format
, ¶ms
);
429 HRESULT
wg_transform_drain(wg_transform_t transform
)
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
);
444 HRESULT
wg_transform_flush(wg_transform_t transform
)
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
);
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
:
470 case WG_VIDEO_FORMAT_BGRA
:
471 case WG_VIDEO_FORMAT_BGRx
:
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");
498 bool wg_video_format_is_rgb(enum wg_video_format 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
:
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
:
523 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, void *reserved
)
525 if (reason
== DLL_PROCESS_ATTACH
)
527 DisableThreadLibraryCalls(instance
);
528 __wine_init_unix_call();
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
))
551 IClassFactory_AddRef(iface
);
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
)
565 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
570 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID iid
, void **out
)
572 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
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
;
582 if (SUCCEEDED(hr
= factory
->create_instance(outer
, &unk
)))
584 hr
= IUnknown_QueryInterface(unk
, iid
, out
);
585 IUnknown_Release(unk
);
590 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL lock
)
592 TRACE("iface %p, lock %d.\n", iface
, lock
);
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
;
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
)))
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
;
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
)
662 if (WINE_UNIX_CALL(unix_wg_init_gstreamer
, NULL
))
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
);
670 ERR("Failed to pin module.\n");
675 BOOL
init_gstreamer(void)
677 static INIT_ONCE once
= INIT_ONCE_STATIC_INIT
;
679 InitOnceExecuteOnce(&once
, init_gstreamer_proc
, NULL
, NULL
);
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] =
694 .lpMediaType
= ®_avi_splitter_sink_mt
,
697 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
699 .lpMediaType
= ®_video_mt
,
703 static const REGFILTER2 reg_avi_splitter
=
706 .dwMerit
= MERIT_NORMAL
,
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] =
727 .lpMediaType
= reg_mpeg_audio_codec_sink_mts
,
730 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
732 .lpMediaType
= reg_mpeg_audio_codec_source_mts
,
736 static const REGFILTER2 reg_mpeg_audio_codec
=
739 .dwMerit
= 0x03680001,
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] =
758 .lpMediaType
= reg_mpeg_layer3_decoder_sink_mts
,
761 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
763 .lpMediaType
= reg_mpeg_layer3_decoder_source_mts
,
767 static const REGFILTER2 reg_mpeg_layer3_decoder
=
770 .dwMerit
= 0x00810000,
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] =
799 .lpMediaType
= reg_mpeg_splitter_sink_mts
,
802 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
804 .lpMediaType
= reg_mpeg_splitter_audio_mts
,
807 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
809 .lpMediaType
= reg_mpeg_splitter_video_mts
,
813 static const REGFILTER2 reg_mpeg_splitter
=
816 .dwMerit
= MERIT_NORMAL
,
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] =
832 .lpMediaType
= reg_wave_parser_sink_mts
,
835 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
837 .lpMediaType
= ®_audio_mt
,
841 static const REGFILTER2 reg_wave_parser
=
844 .dwMerit
= MERIT_UNLIKELY
,
846 .u
.s2
.rgPins2
= reg_wave_parser_pins
,
849 static const REGFILTERPINS2 reg_decodebin_parser_pins
[3] =
853 .lpMediaType
= ®_stream_mt
,
856 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
858 .lpMediaType
= ®_audio_mt
,
861 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
863 .lpMediaType
= ®_video_mt
,
867 static const REGFILTER2 reg_decodebin_parser
=
870 .dwMerit
= MERIT_PREFERRED
,
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
;
967 if (FAILED(hr
= __wine_register_resources()))
970 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
971 &IID_IFilterMapper2
, (void **)&mapper
)))
974 IFilterMapper2_RegisterFilter(mapper
, &CLSID_AviSplitter
, L
"AVI Splitter", NULL
, NULL
, NULL
, ®_avi_splitter
);
975 IFilterMapper2_RegisterFilter(mapper
, &CLSID_decodebin_parser
,
976 L
"GStreamer splitter filter", NULL
, NULL
, NULL
, ®_decodebin_parser
);
977 IFilterMapper2_RegisterFilter(mapper
, &CLSID_CMpegAudioCodec
,
978 L
"MPEG Audio Decoder", NULL
, NULL
, NULL
, ®_mpeg_audio_codec
);
979 IFilterMapper2_RegisterFilter(mapper
, &CLSID_mpeg_layer3_decoder
,
980 L
"MPEG Layer-3 Decoder", NULL
, NULL
, NULL
, ®_mpeg_layer3_decoder
);
981 IFilterMapper2_RegisterFilter(mapper
, &CLSID_MPEG1Splitter
,
982 L
"MPEG-I Stream Splitter", NULL
, NULL
, NULL
, ®_mpeg_splitter
);
983 IFilterMapper2_RegisterFilter(mapper
, &CLSID_WAVEParser
, L
"Wave Parser", NULL
, NULL
, NULL
, ®_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
)))
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
)))
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
)))
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
)))
1000 return mfplat_DllRegisterServer();
1003 HRESULT WINAPI
DllUnregisterServer(void)
1005 IFilterMapper2
*mapper
;
1010 if (FAILED(hr
= __wine_unregister_resources()))
1013 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
1014 &IID_IFilterMapper2
, (void **)&mapper
)))
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
)))
1028 if (FAILED(hr
= DMOUnregister(&CLSID_CResamplerMediaObject
, &DMOCATEGORY_AUDIO_EFFECT
)))
1030 if (FAILED(hr
= DMOUnregister(&CLSID_WMADecMediaObject
, &DMOCATEGORY_AUDIO_DECODER
)))
1032 if (FAILED(hr
= DMOUnregister(&CLSID_WMVDecoderMFT
, &DMOCATEGORY_VIDEO_DECODER
)))