winegstreamer: Reimplement COM registration and vending locally.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7bcb8e74ce
commit
74dc0c5df9
|
@ -5,7 +5,6 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||||
PARENTSRC = ../strmbase
|
PARENTSRC = ../strmbase
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
dllfunc.c \
|
|
||||||
filter.c \
|
filter.c \
|
||||||
gst_cbs.c \
|
gst_cbs.c \
|
||||||
gstdemux.c \
|
gstdemux.c \
|
||||||
|
@ -16,7 +15,8 @@ C_SRCS = \
|
||||||
qualitycontrol.c \
|
qualitycontrol.c \
|
||||||
seeking.c
|
seeking.c
|
||||||
|
|
||||||
IDL_SRCS = mfplat.idl
|
IDL_SRCS = \
|
||||||
|
winegstreamer_classes.idl
|
||||||
|
|
||||||
RC_SRCS = \
|
RC_SRCS = \
|
||||||
rsrc.rc
|
rsrc.rc
|
||||||
|
|
|
@ -22,8 +22,14 @@
|
||||||
#define __GST_PRIVATE_INCLUDED__
|
#define __GST_PRIVATE_INCLUDED__
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/audio/audio.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
#define NONAMELESSSTRUCT
|
||||||
|
#define NONAMELESSUNION
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wtypes.h"
|
#include "wtypes.h"
|
||||||
|
@ -35,16 +41,17 @@
|
||||||
|
|
||||||
#define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
|
#define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
|
||||||
|
|
||||||
IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
|
extern LONG object_locks;
|
||||||
IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
|
|
||||||
IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
|
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
||||||
IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
|
HRESULT gstdemux_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
|
BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
void start_dispatch_thread(void) DECLSPEC_HIDDEN;
|
void start_dispatch_thread(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT mfplat_can_unload_now(void) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
#endif /* __GST_PRIVATE_INCLUDED__ */
|
#endif /* __GST_PRIVATE_INCLUDED__ */
|
||||||
|
|
|
@ -20,11 +20,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
#include <gst/video/video.h>
|
|
||||||
#include <gst/audio/audio.h>
|
|
||||||
|
|
||||||
#include "gst_private.h"
|
#include "gst_private.h"
|
||||||
#include "gst_guids.h"
|
#include "gst_guids.h"
|
||||||
#include "gst_cbs.h"
|
#include "gst_cbs.h"
|
||||||
|
@ -1719,23 +1714,17 @@ static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin,
|
||||||
return VFW_S_NO_MORE_ITEMS;
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
|
HRESULT gstdemux_create(IUnknown *outer, IUnknown **out)
|
||||||
{
|
{
|
||||||
struct gstdemux *object;
|
struct gstdemux *object;
|
||||||
|
|
||||||
if (!init_gstreamer())
|
if (!init_gstreamer())
|
||||||
{
|
return E_FAIL;
|
||||||
*phr = E_FAIL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark_wine_thread();
|
mark_wine_thread();
|
||||||
|
|
||||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
{
|
return E_OUTOFMEMORY;
|
||||||
*phr = E_OUTOFMEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
strmbase_filter_init(&object->filter, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
|
strmbase_filter_init(&object->filter, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
|
||||||
strmbase_sink_init(&object->sink, &object->filter, wcsInputPinName, &sink_ops, NULL);
|
strmbase_sink_init(&object->sink, &object->filter, wcsInputPinName, &sink_ops, NULL);
|
||||||
|
@ -1745,10 +1734,10 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
|
||||||
object->init_gst = gstdecoder_init_gst;
|
object->init_gst = gstdecoder_init_gst;
|
||||||
object->source_query_accept = gstdecoder_source_query_accept;
|
object->source_query_accept = gstdecoder_source_query_accept;
|
||||||
object->source_get_media_type = gstdecoder_source_get_media_type;
|
object->source_get_media_type = gstdecoder_source_get_media_type;
|
||||||
*phr = S_OK;
|
|
||||||
|
|
||||||
TRACE("Created GStreamer demuxer %p.\n", object);
|
TRACE("Created GStreamer demuxer %p.\n", object);
|
||||||
return &object->filter.IUnknown_inner;
|
*out = &object->filter.IUnknown_inner;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gstdemux *impl_from_IAMStreamSelect(IAMStreamSelect *iface)
|
static struct gstdemux *impl_from_IAMStreamSelect(IAMStreamSelect *iface)
|
||||||
|
@ -2422,24 +2411,18 @@ static HRESULT wave_parser_source_get_media_type(struct gstdemux_source *pin,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
|
HRESULT wave_parser_create(IUnknown *outer, IUnknown **out)
|
||||||
{
|
{
|
||||||
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
|
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
|
||||||
struct gstdemux *object;
|
struct gstdemux *object;
|
||||||
|
|
||||||
if (!init_gstreamer())
|
if (!init_gstreamer())
|
||||||
{
|
return E_FAIL;
|
||||||
*phr = E_FAIL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark_wine_thread();
|
mark_wine_thread();
|
||||||
|
|
||||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
{
|
return E_OUTOFMEMORY;
|
||||||
*phr = E_OUTOFMEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
|
strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
|
||||||
strmbase_sink_init(&object->sink, &object->filter, sink_name, &wave_parser_sink_ops, NULL);
|
strmbase_sink_init(&object->sink, &object->filter, sink_name, &wave_parser_sink_ops, NULL);
|
||||||
|
@ -2447,10 +2430,10 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
|
||||||
object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
object->source_query_accept = wave_parser_source_query_accept;
|
object->source_query_accept = wave_parser_source_query_accept;
|
||||||
object->source_get_media_type = wave_parser_source_get_media_type;
|
object->source_get_media_type = wave_parser_source_get_media_type;
|
||||||
*phr = S_OK;
|
|
||||||
|
|
||||||
TRACE("Created WAVE parser %p.\n", object);
|
TRACE("Created WAVE parser %p.\n", object);
|
||||||
return &object->filter.IUnknown_inner;
|
*out = &object->filter.IUnknown_inner;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT avi_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
|
static HRESULT avi_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
|
||||||
|
@ -2543,24 +2526,18 @@ static HRESULT avi_splitter_source_get_media_type(struct gstdemux_source *pin,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
|
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out)
|
||||||
{
|
{
|
||||||
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
|
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
|
||||||
struct gstdemux *object;
|
struct gstdemux *object;
|
||||||
|
|
||||||
if (!init_gstreamer())
|
if (!init_gstreamer())
|
||||||
{
|
return E_FAIL;
|
||||||
*phr = E_FAIL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark_wine_thread();
|
mark_wine_thread();
|
||||||
|
|
||||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
{
|
return E_OUTOFMEMORY;
|
||||||
*phr = E_OUTOFMEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
|
strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
|
||||||
strmbase_sink_init(&object->sink, &object->filter, sink_name, &avi_splitter_sink_ops, NULL);
|
strmbase_sink_init(&object->sink, &object->filter, sink_name, &avi_splitter_sink_ops, NULL);
|
||||||
|
@ -2569,10 +2546,10 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
|
||||||
object->init_gst = avi_splitter_init_gst;
|
object->init_gst = avi_splitter_init_gst;
|
||||||
object->source_query_accept = avi_splitter_source_query_accept;
|
object->source_query_accept = avi_splitter_source_query_accept;
|
||||||
object->source_get_media_type = avi_splitter_source_get_media_type;
|
object->source_get_media_type = avi_splitter_source_get_media_type;
|
||||||
*phr = S_OK;
|
|
||||||
|
|
||||||
TRACE("Created AVI splitter %p.\n", object);
|
TRACE("Created AVI splitter %p.\n", object);
|
||||||
return &object->filter.IUnknown_inner;
|
*out = &object->filter.IUnknown_inner;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT mpeg_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
|
static HRESULT mpeg_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
|
||||||
|
@ -2701,24 +2678,18 @@ static const struct strmbase_filter_ops mpeg_splitter_ops =
|
||||||
.filter_wait_state = gstdemux_wait_state,
|
.filter_wait_state = gstdemux_wait_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
|
HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out)
|
||||||
{
|
{
|
||||||
static const WCHAR sink_name[] = {'I','n','p','u','t',0};
|
static const WCHAR sink_name[] = {'I','n','p','u','t',0};
|
||||||
struct gstdemux *object;
|
struct gstdemux *object;
|
||||||
|
|
||||||
if (!init_gstreamer())
|
if (!init_gstreamer())
|
||||||
{
|
return E_FAIL;
|
||||||
*phr = E_FAIL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark_wine_thread();
|
mark_wine_thread();
|
||||||
|
|
||||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
{
|
return E_OUTOFMEMORY;
|
||||||
*phr = E_OUTOFMEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
|
strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
|
||||||
strmbase_sink_init(&object->sink, &object->filter, sink_name, &mpeg_splitter_sink_ops, NULL);
|
strmbase_sink_init(&object->sink, &object->filter, sink_name, &mpeg_splitter_sink_ops, NULL);
|
||||||
|
@ -2730,8 +2701,8 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
|
||||||
object->source_query_accept = mpeg_splitter_source_query_accept;
|
object->source_query_accept = mpeg_splitter_source_query_accept;
|
||||||
object->source_get_media_type = mpeg_splitter_source_get_media_type;
|
object->source_get_media_type = mpeg_splitter_source_get_media_type;
|
||||||
object->enum_sink_first = TRUE;
|
object->enum_sink_first = TRUE;
|
||||||
*phr = S_OK;
|
|
||||||
|
|
||||||
TRACE("Created MPEG-1 splitter %p.\n", object);
|
TRACE("Created MPEG-1 splitter %p.\n", object);
|
||||||
return &object->filter.IUnknown_inner;
|
*out = &object->filter.IUnknown_inner;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
|
|
||||||
#include "gst_private.h"
|
#include "gst_private.h"
|
||||||
#include "rpcproxy.h"
|
#include "rpcproxy.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -32,7 +26,8 @@
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
#include "gst_guids.h"
|
#include "gst_guids.h"
|
||||||
|
|
||||||
static HINSTANCE hInst = NULL;
|
static HINSTANCE winegstreamer_instance;
|
||||||
|
LONG object_locks;
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
|
WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
|
||||||
|
|
||||||
|
@ -45,249 +40,130 @@ static const WCHAR avi_splitterW[] =
|
||||||
static const WCHAR mpeg_splitterW[] =
|
static const WCHAR mpeg_splitterW[] =
|
||||||
{'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0};
|
{'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0};
|
||||||
|
|
||||||
static WCHAR wNull[] = {'\0'};
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||||
|
{
|
||||||
static const AMOVIESETUP_MEDIATYPE amfMTstream[] =
|
if (reason == DLL_PROCESS_ATTACH)
|
||||||
{ { &MEDIATYPE_Stream, &WINESUBTYPE_Gstreamer },
|
|
||||||
{ &MEDIATYPE_Stream, &MEDIASUBTYPE_NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE amfMTaudio[] =
|
|
||||||
{ { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL } };
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE amfMTvideo[] =
|
|
||||||
{ { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL } };
|
|
||||||
|
|
||||||
static const AMOVIESETUP_PIN amfSplitPin[] =
|
|
||||||
{ { wNull,
|
|
||||||
FALSE, FALSE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
2,
|
|
||||||
amfMTstream
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
wNull,
|
winegstreamer_instance = instance;
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
DisableThreadLibraryCalls(instance);
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
amfMTaudio
|
|
||||||
},
|
|
||||||
{
|
|
||||||
wNull,
|
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
amfMTvideo
|
|
||||||
}
|
}
|
||||||
};
|
return TRUE;
|
||||||
|
|
||||||
static const AMOVIESETUP_FILTER amfSplitter =
|
|
||||||
{ &CLSID_Gstreamer_Splitter,
|
|
||||||
wGstreamer_Splitter,
|
|
||||||
MERIT_PREFERRED,
|
|
||||||
3,
|
|
||||||
amfSplitPin
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE wave_parser_sink_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_AU},
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE wave_parser_source_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Audio, &GUID_NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_PIN wave_parser_pin_data[] =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, FALSE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(wave_parser_sink_type_data),
|
|
||||||
wave_parser_sink_type_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(wave_parser_source_type_data),
|
|
||||||
wave_parser_source_type_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_FILTER wave_parser_filter_data =
|
|
||||||
{
|
|
||||||
&CLSID_WAVEParser,
|
|
||||||
wave_parserW,
|
|
||||||
MERIT_UNLIKELY,
|
|
||||||
ARRAY_SIZE(wave_parser_pin_data),
|
|
||||||
wave_parser_pin_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE avi_splitter_sink_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_PIN avi_splitter_pin_data[] =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, FALSE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(avi_splitter_sink_type_data),
|
|
||||||
avi_splitter_sink_type_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(amfMTvideo),
|
|
||||||
amfMTvideo,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_FILTER avi_splitter_filter_data =
|
|
||||||
{
|
|
||||||
&CLSID_AviSplitter,
|
|
||||||
avi_splitterW,
|
|
||||||
0x5ffff0,
|
|
||||||
ARRAY_SIZE(avi_splitter_pin_data),
|
|
||||||
avi_splitter_pin_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE mpeg_splitter_sink_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video},
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
|
|
||||||
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE mpeg_splitter_audio_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
|
|
||||||
{&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_MEDIATYPE mpeg_splitter_video_type_data[] =
|
|
||||||
{
|
|
||||||
{&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet},
|
|
||||||
{&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_PIN mpeg_splitter_pin_data[] =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, FALSE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(mpeg_splitter_sink_type_data),
|
|
||||||
mpeg_splitter_sink_type_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(mpeg_splitter_audio_type_data),
|
|
||||||
mpeg_splitter_audio_type_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
FALSE, TRUE, FALSE, FALSE,
|
|
||||||
&GUID_NULL,
|
|
||||||
NULL,
|
|
||||||
ARRAY_SIZE(mpeg_splitter_video_type_data),
|
|
||||||
mpeg_splitter_video_type_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AMOVIESETUP_FILTER mpeg_splitter_filter_data =
|
|
||||||
{
|
|
||||||
&CLSID_MPEG1Splitter,
|
|
||||||
mpeg_splitterW,
|
|
||||||
0x5ffff0,
|
|
||||||
ARRAY_SIZE(mpeg_splitter_pin_data),
|
|
||||||
mpeg_splitter_pin_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
FactoryTemplate const g_Templates[] = {
|
|
||||||
{
|
|
||||||
wGstreamer_Splitter,
|
|
||||||
&CLSID_Gstreamer_Splitter,
|
|
||||||
Gstreamer_Splitter_create,
|
|
||||||
NULL,
|
|
||||||
&amfSplitter,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
wave_parserW,
|
|
||||||
&CLSID_WAVEParser,
|
|
||||||
wave_parser_create,
|
|
||||||
NULL,
|
|
||||||
&wave_parser_filter_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
avi_splitterW,
|
|
||||||
&CLSID_AviSplitter,
|
|
||||||
avi_splitter_create,
|
|
||||||
NULL,
|
|
||||||
&avi_splitter_filter_data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mpeg_splitterW,
|
|
||||||
&CLSID_MPEG1Splitter,
|
|
||||||
mpeg_splitter_create,
|
|
||||||
NULL,
|
|
||||||
&mpeg_splitter_filter_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const int g_cTemplates = ARRAY_SIZE(g_Templates);
|
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|
||||||
{
|
|
||||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
|
||||||
hInst = hInstDLL;
|
|
||||||
return STRMBASE_DllMain(hInstDLL, fdwReason, lpv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DllCanUnloadNow
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI DllCanUnloadNow(void)
|
HRESULT WINAPI DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
HRESULT hr = STRMBASE_DllCanUnloadNow();
|
TRACE(".\n");
|
||||||
|
|
||||||
if (hr == S_OK)
|
return object_locks ? S_FALSE : S_OK;
|
||||||
hr = mfplat_can_unload_now();
|
}
|
||||||
|
|
||||||
|
struct class_factory
|
||||||
|
{
|
||||||
|
IClassFactory IClassFactory_iface;
|
||||||
|
HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
|
||||||
|
{
|
||||||
|
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||||
|
|
||||||
|
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
|
||||||
|
{
|
||||||
|
*out = iface;
|
||||||
|
IClassFactory_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI class_factory_Release(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
|
||||||
|
{
|
||||||
|
struct class_factory *factory = impl_from_IClassFactory(iface);
|
||||||
|
IUnknown *unk;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
|
||||||
|
|
||||||
|
if (outer && !IsEqualGUID(iid, &IID_IUnknown))
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
|
||||||
|
{
|
||||||
|
hr = IUnknown_QueryInterface(unk, iid, out);
|
||||||
|
IUnknown_Release(unk);
|
||||||
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
|
||||||
* DllGetClassObject
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
|
||||||
{
|
{
|
||||||
|
TRACE("iface %p, lock %d.\n", iface, lock);
|
||||||
|
|
||||||
|
if (lock)
|
||||||
|
InterlockedIncrement(&object_locks);
|
||||||
|
else
|
||||||
|
InterlockedDecrement(&object_locks);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IClassFactoryVtbl class_factory_vtbl =
|
||||||
|
{
|
||||||
|
class_factory_QueryInterface,
|
||||||
|
class_factory_AddRef,
|
||||||
|
class_factory_Release,
|
||||||
|
class_factory_CreateInstance,
|
||||||
|
class_factory_LockServer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct class_factory avi_splitter_cf = {{&class_factory_vtbl}, avi_splitter_create};
|
||||||
|
static struct class_factory gstdemux_cf = {{&class_factory_vtbl}, gstdemux_create};
|
||||||
|
static struct class_factory mpeg_splitter_cf = {{&class_factory_vtbl}, mpeg_splitter_create};
|
||||||
|
static struct class_factory wave_parser_cf = {{&class_factory_vtbl}, wave_parser_create};
|
||||||
|
|
||||||
|
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
|
||||||
|
{
|
||||||
|
struct class_factory *factory;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (FAILED(hr = mfplat_get_class_object(rclsid, riid, ppv)))
|
TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
|
||||||
hr = STRMBASE_DllGetClassObject( rclsid, riid, ppv );
|
|
||||||
|
|
||||||
return hr;
|
if (SUCCEEDED(hr = mfplat_get_class_object(clsid, iid, out)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (IsEqualGUID(clsid, &CLSID_AviSplitter))
|
||||||
|
factory = &avi_splitter_cf;
|
||||||
|
else if (IsEqualGUID(clsid, &CLSID_Gstreamer_Splitter))
|
||||||
|
factory = &gstdemux_cf;
|
||||||
|
else if (IsEqualGUID(clsid, &CLSID_MPEG1Splitter))
|
||||||
|
factory = &mpeg_splitter_cf;
|
||||||
|
else if (IsEqualGUID(clsid, &CLSID_WAVEParser))
|
||||||
|
factory = &wave_parser_cf;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
|
||||||
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IClassFactory_QueryInterface(&factory->IClassFactory_iface, iid, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ctx)
|
static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ctx)
|
||||||
|
@ -316,9 +192,9 @@ static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ct
|
||||||
/* Unloading glib is a bad idea.. it installs atexit handlers,
|
/* Unloading glib is a bad idea.. it installs atexit handlers,
|
||||||
* so never unload the dll after loading */
|
* so never unload the dll after loading */
|
||||||
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
|
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
|
||||||
(LPCWSTR)hInst, &handle);
|
(LPCWSTR)winegstreamer_instance, &handle);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
ERR("Failed to pin module %p.\n", hInst);
|
ERR("Failed to pin module %p.\n", winegstreamer_instance);
|
||||||
|
|
||||||
start_dispatch_thread();
|
start_dispatch_thread();
|
||||||
}
|
}
|
||||||
|
@ -341,32 +217,176 @@ BOOL init_gstreamer(void)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static const REGPINTYPES reg_audio_mt = {&MEDIATYPE_Audio, &GUID_NULL};
|
||||||
* DllRegisterServer
|
static const REGPINTYPES reg_stream_mt = {&MEDIATYPE_Stream, &GUID_NULL};
|
||||||
*/
|
static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL};
|
||||||
|
|
||||||
|
static const REGPINTYPES reg_avi_splitter_sink_mt = {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi};
|
||||||
|
|
||||||
|
static const REGFILTERPINS2 reg_avi_splitter_pins[2] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_avi_splitter_sink_mt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_video_mt,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTER2 reg_avi_splitter =
|
||||||
|
{
|
||||||
|
.dwVersion = 2,
|
||||||
|
.dwMerit = MERIT_NORMAL,
|
||||||
|
.u.s2.cPins2 = 2,
|
||||||
|
.u.s2.rgPins2 = reg_avi_splitter_pins,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGPINTYPES reg_mpeg_splitter_sink_mts[4] =
|
||||||
|
{
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video},
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGPINTYPES reg_mpeg_splitter_audio_mts[2] =
|
||||||
|
{
|
||||||
|
{&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
|
||||||
|
{&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGPINTYPES reg_mpeg_splitter_video_mts[2] =
|
||||||
|
{
|
||||||
|
{&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet},
|
||||||
|
{&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTERPINS2 reg_mpeg_splitter_pins[3] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.nMediaTypes = 4,
|
||||||
|
.lpMediaType = reg_mpeg_splitter_sink_mts,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 2,
|
||||||
|
.lpMediaType = reg_mpeg_splitter_audio_mts,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 2,
|
||||||
|
.lpMediaType = reg_mpeg_splitter_video_mts,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTER2 reg_mpeg_splitter =
|
||||||
|
{
|
||||||
|
.dwVersion = 2,
|
||||||
|
.dwMerit = MERIT_NORMAL,
|
||||||
|
.u.s2.cPins2 = 3,
|
||||||
|
.u.s2.rgPins2 = reg_mpeg_splitter_pins,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGPINTYPES reg_wave_parser_sink_mts[3] =
|
||||||
|
{
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_AU},
|
||||||
|
{&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTERPINS2 reg_wave_parser_pins[2] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.nMediaTypes = 3,
|
||||||
|
.lpMediaType = reg_wave_parser_sink_mts,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_audio_mt,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTER2 reg_wave_parser =
|
||||||
|
{
|
||||||
|
.dwVersion = 2,
|
||||||
|
.dwMerit = MERIT_UNLIKELY,
|
||||||
|
.u.s2.cPins2 = 2,
|
||||||
|
.u.s2.rgPins2 = reg_wave_parser_pins,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTERPINS2 reg_gstdemux_pins[3] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_stream_mt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_audio_mt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dwFlags = REG_PINFLAG_B_OUTPUT,
|
||||||
|
.nMediaTypes = 1,
|
||||||
|
.lpMediaType = ®_video_mt,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const REGFILTER2 reg_gstdemux =
|
||||||
|
{
|
||||||
|
.dwVersion = 2,
|
||||||
|
.dwMerit = MERIT_PREFERRED,
|
||||||
|
.u.s2.cPins2 = 3,
|
||||||
|
.u.s2.rgPins2 = reg_gstdemux_pins,
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT WINAPI DllRegisterServer(void)
|
HRESULT WINAPI DllRegisterServer(void)
|
||||||
{
|
{
|
||||||
|
IFilterMapper2 *mapper;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE(".\n");
|
||||||
|
|
||||||
hr = AMovieDllRegisterServer2(TRUE);
|
if (FAILED(hr = __wine_register_resources(winegstreamer_instance)))
|
||||||
if (SUCCEEDED(hr))
|
return hr;
|
||||||
hr = __wine_register_resources(hInst);
|
|
||||||
return hr;
|
if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IFilterMapper2, (void **)&mapper)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
IFilterMapper2_RegisterFilter(mapper, &CLSID_AviSplitter, avi_splitterW, NULL, NULL, NULL, ®_avi_splitter);
|
||||||
|
IFilterMapper2_RegisterFilter(mapper, &CLSID_Gstreamer_Splitter,
|
||||||
|
wGstreamer_Splitter, NULL, NULL, NULL, ®_gstdemux);
|
||||||
|
IFilterMapper2_RegisterFilter(mapper, &CLSID_MPEG1Splitter, mpeg_splitterW, NULL, NULL, NULL, ®_mpeg_splitter);
|
||||||
|
IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_wave_parser);
|
||||||
|
|
||||||
|
IFilterMapper2_Release(mapper);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DllUnregisterServer
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI DllUnregisterServer(void)
|
HRESULT WINAPI DllUnregisterServer(void)
|
||||||
{
|
{
|
||||||
|
IFilterMapper2 *mapper;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE(".\n");
|
||||||
|
|
||||||
hr = AMovieDllRegisterServer2(FALSE);
|
if (FAILED(hr = __wine_unregister_resources(winegstreamer_instance)))
|
||||||
if (SUCCEEDED(hr))
|
return hr;
|
||||||
hr = __wine_unregister_resources(hInst);
|
|
||||||
return hr;
|
if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IFilterMapper2, (void **)&mapper)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviSplitter);
|
||||||
|
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_Gstreamer_Splitter);
|
||||||
|
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_MPEG1Splitter);
|
||||||
|
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_WAVEParser);
|
||||||
|
|
||||||
|
IFilterMapper2_Release(mapper);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#include "gst_private.h"
|
||||||
#define NONAMELESSUNION
|
|
||||||
|
|
||||||
#include "mfapi.h"
|
#include "mfapi.h"
|
||||||
#include "mfidl.h"
|
#include "mfidl.h"
|
||||||
|
|
||||||
|
@ -29,8 +27,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||||
|
|
||||||
static LONG object_locks;
|
|
||||||
|
|
||||||
struct video_processor
|
struct video_processor
|
||||||
{
|
{
|
||||||
IMFTransform IMFTransform_iface;
|
IMFTransform IMFTransform_iface;
|
||||||
|
@ -437,8 +433,3 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||||
|
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT mfplat_can_unload_now(void)
|
|
||||||
{
|
|
||||||
return !object_locks ? S_OK : S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 Nikolay Sivov for CodeWeavers
|
* COM classes for winegstreamer
|
||||||
|
*
|
||||||
|
* Copyright 2019 Nikolay Sivov
|
||||||
|
* Copyright 2019 Zebediah Figura
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -18,9 +21,36 @@
|
||||||
|
|
||||||
#pragma makedep register
|
#pragma makedep register
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("AVI Splitter"),
|
||||||
|
threading(both),
|
||||||
|
uuid(1b544c20-fd0b-11ce-8c63-00aa0044b51e)
|
||||||
|
]
|
||||||
|
coclass AviSplitter {}
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("MPEG-I Stream Splitter"),
|
||||||
|
threading(both),
|
||||||
|
uuid(336475d0-942a-11ce-a870-00aa002feab5)
|
||||||
|
]
|
||||||
|
coclass MPEG1Splitter {}
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("Wave Parser"),
|
||||||
|
threading(both),
|
||||||
|
uuid(d51bd5a1-7548-11cf-a520-0080c77ef58a)
|
||||||
|
]
|
||||||
|
coclass WAVEParser {}
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("GStreamer splitter"),
|
||||||
|
threading(both),
|
||||||
|
uuid(f9d8d64e-a144-47dc-8ee0-f53498372c29)
|
||||||
|
]
|
||||||
|
coclass Gstreamer_Splitter {}
|
||||||
|
|
||||||
[
|
[
|
||||||
threading(both),
|
threading(both),
|
||||||
uuid(88753b26-5b24-49bd-b2e7-0c445c78c982)
|
uuid(88753b26-5b24-49bd-b2e7-0c445c78c982)
|
||||||
|
|
||||||
]
|
]
|
||||||
coclass VideoProcessorMFT { }
|
coclass VideoProcessorMFT {}
|
Loading…
Reference in New Issue