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 #include "gst_private.h"
28 #include "gst_guids.h"
30 static HINSTANCE winegstreamer_instance
;
33 WINE_DEFAULT_DEBUG_CHANNEL(gstreamer
);
35 const struct unix_funcs
*unix_funcs
= NULL
;
37 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, void *reserved
)
39 if (reason
== DLL_PROCESS_ATTACH
)
41 winegstreamer_instance
= instance
;
42 DisableThreadLibraryCalls(instance
);
43 __wine_init_unix_lib(instance
, reason
, NULL
, &unix_funcs
);
48 HRESULT WINAPI
DllCanUnloadNow(void)
52 return object_locks
? S_FALSE
: S_OK
;
57 IClassFactory IClassFactory_iface
;
58 HRESULT (*create_instance
)(IUnknown
*outer
, IUnknown
**out
);
61 static inline struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
63 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
66 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID iid
, void **out
)
68 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
70 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IClassFactory
))
73 IClassFactory_AddRef(iface
);
78 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
82 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
87 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
92 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID iid
, void **out
)
94 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
98 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface
, outer
, debugstr_guid(iid
), out
);
100 if (outer
&& !IsEqualGUID(iid
, &IID_IUnknown
))
101 return E_NOINTERFACE
;
104 if (SUCCEEDED(hr
= factory
->create_instance(outer
, &unk
)))
106 hr
= IUnknown_QueryInterface(unk
, iid
, out
);
107 IUnknown_Release(unk
);
112 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL lock
)
114 TRACE("iface %p, lock %d.\n", iface
, lock
);
117 InterlockedIncrement(&object_locks
);
119 InterlockedDecrement(&object_locks
);
123 static const IClassFactoryVtbl class_factory_vtbl
=
125 class_factory_QueryInterface
,
126 class_factory_AddRef
,
127 class_factory_Release
,
128 class_factory_CreateInstance
,
129 class_factory_LockServer
,
132 static struct class_factory avi_splitter_cf
= {{&class_factory_vtbl
}, avi_splitter_create
};
133 static struct class_factory decodebin_parser_cf
= {{&class_factory_vtbl
}, decodebin_parser_create
};
134 static struct class_factory mpeg_splitter_cf
= {{&class_factory_vtbl
}, mpeg_splitter_create
};
135 static struct class_factory wave_parser_cf
= {{&class_factory_vtbl
}, wave_parser_create
};
137 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID iid
, void **out
)
139 struct class_factory
*factory
;
142 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid
), debugstr_guid(iid
), out
);
144 if (!init_gstreamer())
145 return CLASS_E_CLASSNOTAVAILABLE
;
147 if (SUCCEEDED(hr
= mfplat_get_class_object(clsid
, iid
, out
)))
150 if (IsEqualGUID(clsid
, &CLSID_AviSplitter
))
151 factory
= &avi_splitter_cf
;
152 else if (IsEqualGUID(clsid
, &CLSID_decodebin_parser
))
153 factory
= &decodebin_parser_cf
;
154 else if (IsEqualGUID(clsid
, &CLSID_MPEG1Splitter
))
155 factory
= &mpeg_splitter_cf
;
156 else if (IsEqualGUID(clsid
, &CLSID_WAVEParser
))
157 factory
= &wave_parser_cf
;
160 FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid
));
161 return CLASS_E_CLASSNOTAVAILABLE
;
164 return IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, iid
, out
);
167 static BOOL CALLBACK
init_gstreamer_proc(INIT_ONCE
*once
, void *param
, void **ctx
)
171 /* Unloading glib is a bad idea.. it installs atexit handlers,
172 * so never unload the dll after loading */
173 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
| GET_MODULE_HANDLE_EX_FLAG_PIN
,
174 (LPCWSTR
)winegstreamer_instance
, &handle
);
176 ERR("Failed to pin module %p.\n", winegstreamer_instance
);
181 BOOL
init_gstreamer(void)
183 static INIT_ONCE once
= INIT_ONCE_STATIC_INIT
;
185 InitOnceExecuteOnce(&once
, init_gstreamer_proc
, NULL
, NULL
);
190 static const REGPINTYPES reg_audio_mt
= {&MEDIATYPE_Audio
, &GUID_NULL
};
191 static const REGPINTYPES reg_stream_mt
= {&MEDIATYPE_Stream
, &GUID_NULL
};
192 static const REGPINTYPES reg_video_mt
= {&MEDIATYPE_Video
, &GUID_NULL
};
194 static const REGPINTYPES reg_avi_splitter_sink_mt
= {&MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
};
196 static const REGFILTERPINS2 reg_avi_splitter_pins
[2] =
200 .lpMediaType
= ®_avi_splitter_sink_mt
,
203 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
205 .lpMediaType
= ®_video_mt
,
209 static const REGFILTER2 reg_avi_splitter
=
212 .dwMerit
= MERIT_NORMAL
,
214 .u
.s2
.rgPins2
= reg_avi_splitter_pins
,
217 static const REGPINTYPES reg_mpeg_splitter_sink_mts
[4] =
219 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
220 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
221 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
222 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
225 static const REGPINTYPES reg_mpeg_splitter_audio_mts
[2] =
227 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
228 {&MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
231 static const REGPINTYPES reg_mpeg_splitter_video_mts
[2] =
233 {&MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
234 {&MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
237 static const REGFILTERPINS2 reg_mpeg_splitter_pins
[3] =
241 .lpMediaType
= reg_mpeg_splitter_sink_mts
,
244 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
246 .lpMediaType
= reg_mpeg_splitter_audio_mts
,
249 .dwFlags
= REG_PINFLAG_B_ZERO
| REG_PINFLAG_B_OUTPUT
,
251 .lpMediaType
= reg_mpeg_splitter_video_mts
,
255 static const REGFILTER2 reg_mpeg_splitter
=
258 .dwMerit
= MERIT_NORMAL
,
260 .u
.s2
.rgPins2
= reg_mpeg_splitter_pins
,
263 static const REGPINTYPES reg_wave_parser_sink_mts
[3] =
265 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
266 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
267 {&MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
270 static const REGFILTERPINS2 reg_wave_parser_pins
[2] =
274 .lpMediaType
= reg_wave_parser_sink_mts
,
277 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
279 .lpMediaType
= ®_audio_mt
,
283 static const REGFILTER2 reg_wave_parser
=
286 .dwMerit
= MERIT_UNLIKELY
,
288 .u
.s2
.rgPins2
= reg_wave_parser_pins
,
291 static const REGFILTERPINS2 reg_decodebin_parser_pins
[3] =
295 .lpMediaType
= ®_stream_mt
,
298 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
300 .lpMediaType
= ®_audio_mt
,
303 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
305 .lpMediaType
= ®_video_mt
,
309 static const REGFILTER2 reg_decodebin_parser
=
312 .dwMerit
= MERIT_PREFERRED
,
314 .u
.s2
.rgPins2
= reg_decodebin_parser_pins
,
317 HRESULT WINAPI
DllRegisterServer(void)
319 IFilterMapper2
*mapper
;
324 if (FAILED(hr
= __wine_register_resources(winegstreamer_instance
)))
327 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
328 &IID_IFilterMapper2
, (void **)&mapper
)))
331 IFilterMapper2_RegisterFilter(mapper
, &CLSID_AviSplitter
, L
"AVI Splitter", NULL
, NULL
, NULL
, ®_avi_splitter
);
332 IFilterMapper2_RegisterFilter(mapper
, &CLSID_decodebin_parser
,
333 L
"GStreamer splitter filter", NULL
, NULL
, NULL
, ®_decodebin_parser
);
334 IFilterMapper2_RegisterFilter(mapper
, &CLSID_MPEG1Splitter
,
335 L
"MPEG-I Stream Splitter", NULL
, NULL
, NULL
, ®_mpeg_splitter
);
336 IFilterMapper2_RegisterFilter(mapper
, &CLSID_WAVEParser
, L
"Wave Parser", NULL
, NULL
, NULL
, ®_wave_parser
);
338 IFilterMapper2_Release(mapper
);
340 return mfplat_DllRegisterServer();
343 HRESULT WINAPI
DllUnregisterServer(void)
345 IFilterMapper2
*mapper
;
350 if (FAILED(hr
= __wine_unregister_resources(winegstreamer_instance
)))
353 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
354 &IID_IFilterMapper2
, (void **)&mapper
)))
357 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_AviSplitter
);
358 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_decodebin_parser
);
359 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_MPEG1Splitter
);
360 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_WAVEParser
);
362 IFilterMapper2_Release(mapper
);