In the unlikely event that we are hotplugging not from an IAsyncReader, we already have the ACM wrapper and l3codeca.acm available to do the same thing.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/Makefile.in | 4 +- dlls/winegstreamer/gst_cbs.c | 24 -- dlls/winegstreamer/gst_cbs.h | 13 - dlls/winegstreamer/gst_guids.h | 1 - dlls/winegstreamer/gst_private.h | 7 - dlls/winegstreamer/gstdemux.c | 14 +- dlls/winegstreamer/gsttffilter.c | 628 ------------------------------- dlls/winegstreamer/main.c | 35 -- 8 files changed, 2 insertions(+), 724 deletions(-) delete mode 100644 dlls/winegstreamer/gsttffilter.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 08adb2b6d5d..c536f2521c0 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -10,14 +10,12 @@ C_SRCS = \ filter.c \ gst_cbs.c \ gstdemux.c \ - gsttffilter.c \ main.c \ mediatype.c \ mfplat.c \ pin.c \ qualitycontrol.c \ - seeking.c \ - transform.c + seeking.c
IDL_SRCS = mfplat.idl
diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c index c8ba812c8a7..e7a4b41d55f 100644 --- a/dlls/winegstreamer/gst_cbs.c +++ b/dlls/winegstreamer/gst_cbs.c @@ -188,19 +188,6 @@ GstFlowReturn got_data_sink_wrapper(GstPad *pad, GstObject *parent, GstBuffer *b return cbdata.u.got_data_sink_data.ret; }
-GstFlowReturn got_data_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) -{ - struct cb_data cbdata = { GOT_DATA }; - - cbdata.u.got_data_data.pad = pad; - cbdata.u.got_data_data.parent = parent; - cbdata.u.got_data_data.buf = buf; - - call_cb(&cbdata); - - return cbdata.u.got_data_data.ret; -} - void removed_decoded_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) { struct cb_data cbdata = { REMOVED_DECODED_PAD }; @@ -249,17 +236,6 @@ void release_sample_wrapper(gpointer data) call_cb(&cbdata); }
-void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) -{ - struct cb_data cbdata = { TRANSFORM_PAD_ADDED }; - - cbdata.u.transform_pad_added_data.filter = filter; - cbdata.u.transform_pad_added_data.pad = pad; - cbdata.u.transform_pad_added_data.user = user; - - call_cb(&cbdata); -} - gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) { struct cb_data cbdata = { QUERY_SINK }; diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h index 100a8dece44..46f8add57c4 100644 --- a/dlls/winegstreamer/gst_cbs.h +++ b/dlls/winegstreamer/gst_cbs.h @@ -39,12 +39,10 @@ enum CB_TYPE { EVENT_SRC, EVENT_SINK, GOT_DATA_SINK, - GOT_DATA, REMOVED_DECODED_PAD, AUTOPLUG_BLACKLIST, UNKNOWN_TYPE, RELEASE_SAMPLE, - TRANSFORM_PAD_ADDED, QUERY_SINK };
@@ -105,12 +103,6 @@ struct cb_data { GstBuffer *buf; GstFlowReturn ret; } got_data_sink_data; - struct got_data_data { - GstPad *pad; - GstObject *parent; - GstBuffer *buf; - GstFlowReturn ret; - } got_data_data; struct removed_decoded_pad_data { GstElement *bin; GstPad *pad; @@ -133,11 +125,6 @@ struct cb_data { struct release_sample_data { gpointer data; } release_sample_data; - struct transform_pad_added_data { - GstElement *filter; - GstPad *pad; - gpointer user; - } transform_pad_added_data; struct query_sink_data { GstPad *pad; GstObject *parent; diff --git a/dlls/winegstreamer/gst_guids.h b/dlls/winegstreamer/gst_guids.h index e50ecb48519..b5ed3139b60 100644 --- a/dlls/winegstreamer/gst_guids.h +++ b/dlls/winegstreamer/gst_guids.h @@ -19,6 +19,5 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-DEFINE_GUID(CLSID_Gstreamer_Mp3, 0x728dcf55, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa); DEFINE_GUID(CLSID_Gstreamer_Splitter, 0xf9d8d64e, 0xa144, 0x47dc, 0x8e, 0xe0, 0xf5, 0x34, 0x98, 0x37, 0x2c, 0x29); DEFINE_GUID(WINESUBTYPE_Gstreamer, 0xffffffff, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 7108a32e401..353ff0bbd5b 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -37,20 +37,13 @@
IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN; IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN; -IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
-GstFlowReturn got_data(GstPad *pad, GstObject *parent, GstBuffer *buf) DECLSPEC_HIDDEN; -GstFlowReturn request_buffer(GstPad *pad, guint64 ofs, guint size, GstCaps *caps, GstBuffer **buf) DECLSPEC_HIDDEN; -void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; - void start_dispatch_thread(void) DECLSPEC_HIDDEN;
-extern const char *media_quark_string 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;
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index f9eed906b6e..0b5fee30273 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -97,7 +97,7 @@ static inline struct gstdemux *impl_from_strmbase_filter(struct strmbase_filter return CONTAINING_RECORD(iface, struct gstdemux, filter); }
-const char* media_quark_string = "media-sample"; +static const char *media_quark_string = "media-sample";
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; static const IMediaSeekingVtbl GST_Seeking_Vtbl; @@ -2313,12 +2313,6 @@ void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) cbdata->u.got_data_sink_data.ret = got_data_sink(data->pad, data->parent, data->buf); break; } - case GOT_DATA: - { - struct got_data_data *data = &cbdata->u.got_data_data; - cbdata->u.got_data_data.ret = got_data(data->pad, data->parent, data->buf); - break; - } case REMOVED_DECODED_PAD: { struct removed_decoded_pad_data *data = &cbdata->u.removed_decoded_pad_data; @@ -2344,12 +2338,6 @@ void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) release_sample(data->data); break; } - case TRANSFORM_PAD_ADDED: - { - struct transform_pad_added_data *data = &cbdata->u.transform_pad_added_data; - Gstreamer_transform_pad_added(data->filter, data->pad, data->user); - break; - } case QUERY_SINK: { struct query_sink_data *data = &cbdata->u.query_sink_data; diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c deleted file mode 100644 index 21feefe09d2..00000000000 --- a/dlls/winegstreamer/gsttffilter.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * GStreamer wrapper filter - * - * Copyright 2010 Maarten Lankhorst for CodeWeavers - * Copyright 2010 Aric Stewart for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include "config.h" - -#include <gst/gst.h> -#include <gst/video/video.h> -#include <gst/audio/audio.h> - -#include "gst_private.h" -#include "gst_guids.h" -#include "gst_cbs.h" - -#include "uuids.h" -#include "mmreg.h" -#include "windef.h" -#include "winbase.h" -#include "dshow.h" -#include "strmif.h" -#include "vfwmsgs.h" -#include "dvdmedia.h" -#include "ks.h" -#include "ksmedia.h" -#include "msacm.h" - -#include <assert.h> - -#include "wine/unicode.h" -#include "wine/debug.h" - -#include "initguid.h" -DEFINE_GUID(WMMEDIASUBTYPE_MP3, 0x00000055, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - -WINE_DEFAULT_DEBUG_CHANNEL(gstreamer); - -struct typeinfo { - GstCaps *caps; - const char *type; -}; - -static gboolean match_element(GstPluginFeature *feature, gpointer gdata) -{ - struct typeinfo *data = (struct typeinfo*)gdata; - GstElementFactory *factory; - const GList *list; - - if (!GST_IS_ELEMENT_FACTORY(feature)) - return FALSE; - factory = GST_ELEMENT_FACTORY(feature); - if (!strstr(gst_element_factory_get_klass(factory), data->type)) - return FALSE; - for (list = gst_element_factory_get_static_pad_templates(factory); list; list = list->next) { - GstStaticPadTemplate *pad = (GstStaticPadTemplate*)list->data; - GstCaps *caps; - gboolean ret; - if (pad->direction != GST_PAD_SINK) - continue; - caps = gst_static_caps_get(&pad->static_caps); - ret = gst_caps_is_always_compatible(caps, data->caps); - gst_caps_unref(caps); - if (ret) - return TRUE; - } - return FALSE; -} - -static const char *Gstreamer_FindMatch(const char *strcaps) -{ - struct typeinfo data; - GList *list, *copy; - guint bestrank = 0; - GstElementFactory *bestfactory = NULL; - GstCaps *caps = gst_caps_from_string(strcaps); - - TRACE("%s\n", strcaps); - - data.caps = caps; - data.type = "Decoder"; - copy = gst_registry_feature_filter(gst_registry_get(), match_element, 0, &data); - for (list = copy; list; list = list->next) { - GstElementFactory *factory = (GstElementFactory*)list->data; - guint rank; - rank = gst_plugin_feature_get_rank(GST_PLUGIN_FEATURE(factory)); - if (rank > bestrank || !bestrank) { - bestrank = rank; - bestfactory = factory; - } - } - gst_caps_unref(caps); - g_list_free(copy); - - if (!bestfactory) { - ERR("Could not find plugin for %s\n", strcaps); - return NULL; - } - return gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(bestfactory)); -} - -typedef struct GstTfImpl { - TransformFilter tf; - const char *gstreamer_name; - GstElement *filter; - GstPad *my_src, *my_sink, *their_src, *their_sink; - LONG cbBuffer; -} GstTfImpl; - -static HRESULT WINAPI Gstreamer_transform_ProcessBegin(TransformFilter *iface) -{ - GstTfImpl *This = (GstTfImpl*)iface; - int ret; - - mark_wine_thread(); - - ret = gst_element_set_state(This->filter, GST_STATE_PLAYING); - TRACE("Returned: %i\n", ret); - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_DecideBufferSize(TransformFilter *tf, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) -{ - GstTfImpl *This = (GstTfImpl*)tf; - ALLOCATOR_PROPERTIES actual; - - TRACE("%p, %p, %p\n", This, pAlloc, ppropInputRequest); - - if (!ppropInputRequest->cbAlign) - ppropInputRequest->cbAlign = 1; - - ppropInputRequest->cbBuffer = This->cbBuffer; - - if (ppropInputRequest->cBuffers < 2) - ppropInputRequest->cBuffers = 2; - - return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual); -} - -GstFlowReturn got_data(GstPad *pad, GstObject *parent, GstBuffer *buf) -{ - GstTfImpl *This = gst_pad_get_element_private(pad); - IMediaSample *sample = (IMediaSample *) gst_mini_object_get_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string)); - REFERENCE_TIME tStart, tStop; - HRESULT hr; - - TRACE("%p, %p\n", pad, buf); - - if(!sample){ - GstMapInfo info; - BYTE *ptr; - - gst_buffer_map(buf, &info, GST_MAP_READ); - - hr = BaseOutputPinImpl_GetDeliveryBuffer(&This->tf.source, &sample, NULL, NULL, 0); - if (FAILED(hr)) { - ERR("Could not get output buffer: %08x\n", hr); - return GST_FLOW_FLUSHING; - } - - IMediaSample_SetActualDataLength(sample, info.size); - - IMediaSample_GetPointer(sample, &ptr); - - memcpy(ptr, info.data, info.size); - - gst_buffer_unmap(buf, &info); - } - - if (GST_BUFFER_PTS_IS_VALID(buf) && - GST_BUFFER_DURATION_IS_VALID(buf)) { - tStart = buf->pts / 100; - tStop = tStart + buf->duration / 100; - IMediaSample_SetTime(sample, &tStart, &tStop); - } - else - IMediaSample_SetTime(sample, NULL, NULL); - if (GST_BUFFER_OFFSET_IS_VALID(buf) && - GST_BUFFER_OFFSET_END_IS_VALID(buf)) { - tStart = buf->offset / 100; - tStop = buf->offset_end / 100; - IMediaSample_SetMediaTime(sample, &tStart, &tStop); - } - else - IMediaSample_SetMediaTime(sample, NULL, NULL); - - IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); - IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LIVE)); - IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)); - IMediaSample_SetActualDataLength(sample, gst_buffer_get_size(buf)); - - hr = IMemInputPin_Receive(This->tf.source.pMemInputPin, sample); - IMediaSample_Release(sample); - gst_buffer_unref(buf); - if (FAILED(hr)) - return GST_FLOW_FLUSHING; - return GST_FLOW_OK; -} - -static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IMediaSample *sample) -{ - GstTfImpl *This = (GstTfImpl*)iface; - REFERENCE_TIME tStart, tStop; - BYTE *data; - GstBuffer *buf; - HRESULT hr; - DWORD bufsize; - int ret; - - TRACE("%p, %p\n", This, sample); - - mark_wine_thread(); - - IMediaSample_GetPointer(sample, &data); - - IMediaSample_AddRef(sample); - bufsize = IMediaSample_GetActualDataLength(sample); - buf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, sample, release_sample_wrapper); - if (!buf) { - IMediaSample_Release(sample); - return S_OK; - } - - IMediaSample_AddRef(sample); - gst_mini_object_set_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string), sample, release_sample_wrapper); - - buf->duration = buf->pts = -1; - hr = IMediaSample_GetTime(sample, &tStart, &tStop); - if (SUCCEEDED(hr)) { - buf->pts = tStart * 100; - if (hr == S_OK) - buf->duration = (tStop - tStart)*100; - } - if (IMediaSample_GetMediaTime(sample, &tStart, &tStop) == S_OK) { - buf->offset = tStart * 100; - buf->offset_end = tStop * 100; - } - if (IMediaSample_IsDiscontinuity(sample) == S_OK) - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DISCONT); - if (IMediaSample_IsPreroll(sample) == S_OK) - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_LIVE); - if (IMediaSample_IsSyncPoint(sample) != S_OK) - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT); - ret = gst_pad_push(This->my_src, buf); - if (ret) - WARN("Sending returned: %i\n", ret); - if (ret == GST_FLOW_FLUSHING) - return VFW_E_WRONG_STATE; - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_ProcessEnd(TransformFilter *iface) -{ - GstTfImpl *This = (GstTfImpl*)iface; - int ret; - - mark_wine_thread(); - - ret = gst_element_set_state(This->filter, GST_STATE_READY); - TRACE("Returned: %i\n", ret); - return S_OK; -} - -void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, gpointer user) -{ - GstTfImpl *This = (GstTfImpl*)user; - int ret; - - TRACE("%p %p %p\n", This, filter, pad); - - if (!GST_PAD_IS_SRC(pad)) - return; - - ret = gst_pad_link(pad, This->my_sink); - if (ret < 0) - WARN("Failed to link with %i\n", ret); - This->their_src = pad; -} - -static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) -{ - GstIterator *it; - BOOL done = FALSE, found = FALSE; - int ret; - - TRACE("%p %p %p %p\n", This, amt, capsin, capsout); - - mark_wine_thread(); - - This->filter = gst_element_factory_make(This->gstreamer_name, NULL); - if (!This->filter) { - ERR("Could not make %s filter\n", This->gstreamer_name); - return E_FAIL; - } - This->my_src = gst_pad_new("yuvsrc", GST_PAD_SRC); - gst_pad_set_element_private (This->my_src, This); - gst_pad_set_active(This->my_src, 1); - - This->my_sink = gst_pad_new("yuvsink", GST_PAD_SINK); - gst_pad_set_chain_function(This->my_sink, got_data_wrapper); - gst_pad_set_element_private (This->my_sink, This); - gst_pad_set_active(This->my_sink, 1); - - it = gst_element_iterate_sink_pads(This->filter); - while (!done) { - GValue item = {0}; - - switch (gst_iterator_next(it, &item)) { - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - case GST_ITERATOR_OK: - This->their_sink = g_value_get_object(&item); - gst_object_ref(This->their_sink); - g_value_reset(&item); - case GST_ITERATOR_ERROR: - case GST_ITERATOR_DONE: - done = TRUE; - break; - } - } - gst_iterator_free(it); - if (!This->their_sink) { - ERR("Could not find sink on filter %s\n", This->gstreamer_name); - return E_FAIL; - } - - it = gst_element_iterate_src_pads(This->filter); - gst_iterator_resync(it); - done = FALSE; - while (!done) { - GValue item = {0}; - - switch (gst_iterator_next(it, &item)) { - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - case GST_ITERATOR_OK: - This->their_src = g_value_get_object(&item); - gst_object_ref(This->their_src); - g_value_reset(&item); - case GST_ITERATOR_ERROR: - case GST_ITERATOR_DONE: - done = TRUE; - break; - } - } - gst_iterator_free(it); - found = !!This->their_src; - if (!found) - g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added_wrapper), This); - ret = gst_pad_link(This->my_src, This->their_sink); - if (ret < 0) { - WARN("Failed to link with %i\n", ret); - return E_FAIL; - } - - ret = gst_pad_set_caps(This->my_src, capsin); - if (ret < 0) { - WARN("Failed to set caps on own source with %i\n", ret); - return E_FAIL; - } - - if (found) - Gstreamer_transform_pad_added(This->filter, This->their_src, This); - - if (!gst_pad_is_linked(This->my_sink)) - return E_FAIL; - - ret = gst_pad_set_caps(This->my_sink, capsout); - if (ret < 0) { - WARN("Failed to set caps on own sink with %i\n", ret); - return E_FAIL; - } - - TRACE("Connected\n"); - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_Cleanup(TransformFilter *tf, PIN_DIRECTION dir) -{ - GstTfImpl *This = (GstTfImpl*)tf; - - TRACE("%p 0x%x\n", This, dir); - - mark_wine_thread(); - - if (dir == PINDIR_INPUT) - { - if (This->filter) { - gst_element_set_state(This->filter, GST_STATE_NULL); - gst_object_unref(This->filter); - } - This->filter = NULL; - if (This->my_src) { - gst_pad_unlink(This->my_src, This->their_sink); - gst_object_unref(This->my_src); - gst_object_unref(This->their_sink); - } - if (This->my_sink) { - gst_pad_unlink(This->their_src, This->my_sink); - gst_object_unref(This->my_sink); - gst_object_unref(This->their_src); - } - This->my_sink = This->my_src = This->their_sink = This->their_src = NULL; - } - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_EndOfStream(TransformFilter *iface) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p\n", This); - mark_wine_thread(); - - gst_pad_push_event(This->my_src, gst_event_new_eos()); - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_BeginFlush(TransformFilter *iface) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p\n", This); - mark_wine_thread(); - - gst_pad_push_event(This->my_src, gst_event_new_flush_start()); - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_EndFlush(TransformFilter *iface) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p\n", This); - mark_wine_thread(); - - gst_pad_push_event(This->my_src, gst_event_new_flush_stop(TRUE)); - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_NewSegment(TransformFilter *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - GstTfImpl *This = (GstTfImpl*)iface; - const GstSegment segment = { GST_SEGMENT_FLAG_NONE, 1.0, dRate, GST_FORMAT_TIME, 0, 0, 0, tStop <= tStart ? -1 : tStop * 100, 0, tStart*100, -1 }; - - TRACE("%p\n", This); - mark_wine_thread(); - - gst_pad_push_event(This->my_src, gst_event_new_segment(&segment)); - - return S_OK; -} - -static HRESULT WINAPI Gstreamer_transform_QOS(TransformFilter *iface, IBaseFilter *sender, Quality qm) -{ - GstTfImpl *This = (GstTfImpl*)iface; - REFERENCE_TIME late = qm.Late; - - TRACE("%p %p { 0x%x %u %s %s }\n", This, sender, - qm.Type, qm.Proportion, - wine_dbgstr_longlong(qm.Late), - wine_dbgstr_longlong(qm.TimeStamp)); - - mark_wine_thread(); - - if (qm.Late < 0 && -qm.Late > qm.TimeStamp) - late = -qm.TimeStamp; - gst_pad_push_event(This->my_sink, gst_event_new_qos(late <= 0 ? GST_QOS_TYPE_OVERFLOW : GST_QOS_TYPE_UNDERFLOW, 1000. / qm.Proportion, late * 100, qm.TimeStamp * 100)); - return TransformFilterImpl_Notify(iface, sender, qm); -} - -static HRESULT Gstreamer_transform_create(IUnknown *outer, const CLSID *clsid, - const char *name, const TransformFilterFuncTable *vtbl, void **obj) -{ - GstTfImpl *This; - - if (FAILED(strmbase_transform_create(sizeof(GstTfImpl), outer, clsid, vtbl, (IBaseFilter **)&This))) - return E_OUTOFMEMORY; - - This->gstreamer_name = name; - *obj = &This->tf.filter.IUnknown_inner; - - TRACE("returning %p\n", This); - - return S_OK; -} - -static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p %p\n", This, amt); - - if ( (!IsEqualGUID(&amt->majortype, &MEDIATYPE_Audio) && - !IsEqualGUID(&amt->majortype, &MEDIATYPE_Stream)) || - (!IsEqualGUID(&amt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload) && - !IsEqualGUID(&amt->subtype, &WMMEDIASUBTYPE_MP3)) - || !IsEqualGUID(&amt->formattype, &FORMAT_WaveFormatEx)){ - return S_FALSE; - } - - return S_OK; -} - -static HRESULT mp3_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)tf; - GstCaps *capsin, *capsout; - AM_MEDIA_TYPE *outpmt = &This->tf.pmt; - WAVEFORMATEX *wfx, *wfxin; - HRESULT hr; - int layer; - - mark_wine_thread(); - - if (Gstreamer_Mp3_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat) - return VFW_E_TYPE_NOT_ACCEPTED; - - wfxin = (WAVEFORMATEX*)amt->pbFormat; - switch (wfxin->wFormatTag) { - case WAVE_FORMAT_MPEGLAYER3: - layer = 3; - break; - case WAVE_FORMAT_MPEG: { - MPEG1WAVEFORMAT *mpgformat = (MPEG1WAVEFORMAT*)wfxin; - layer = mpgformat->fwHeadLayer; - break; - } - default: - FIXME("Unhandled tag %x\n", wfxin->wFormatTag); - return E_FAIL; - } - - FreeMediaType(outpmt); - CopyMediaType(outpmt, amt); - - outpmt->subtype = MEDIASUBTYPE_PCM; - outpmt->formattype = FORMAT_WaveFormatEx; - outpmt->cbFormat = sizeof(*wfx); - CoTaskMemFree(outpmt->pbFormat); - wfx = CoTaskMemAlloc(outpmt->cbFormat); - outpmt->pbFormat = (BYTE*)wfx; - wfx->wFormatTag = WAVE_FORMAT_PCM; - wfx->wBitsPerSample = 16; - wfx->nSamplesPerSec = wfxin->nSamplesPerSec; - wfx->nChannels = wfxin->nChannels; - wfx->nBlockAlign = wfx->wBitsPerSample * wfx->nChannels / 8; - wfx->cbSize = 0; - wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign; - - capsin = gst_caps_new_simple("audio/mpeg", - "mpegversion", G_TYPE_INT, 1, - "layer", G_TYPE_INT, layer, - "rate", G_TYPE_INT, wfx->nSamplesPerSec, - "channels", G_TYPE_INT, wfx->nChannels, - NULL); - capsout = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, "S16LE", - "rate", G_TYPE_INT, wfx->nSamplesPerSec, - "channels", G_TYPE_INT, wfx->nChannels, - NULL); - - hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); - gst_caps_unref(capsin); - gst_caps_unref(capsout); - - This->cbBuffer = wfx->nAvgBytesPerSec / 4; - - return hr; -} - -static const TransformFilterFuncTable Gstreamer_Mp3_vtbl = { - .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize, - .pfnStartStreaming = Gstreamer_transform_ProcessBegin, - .pfnReceive = Gstreamer_transform_ProcessData, - .pfnStopStreaming = Gstreamer_transform_ProcessEnd, - .pfnCheckInputType = Gstreamer_Mp3_QueryConnect, - .transform_connect_sink = mp3_decoder_connect_sink, - .pfnBreakConnect = Gstreamer_transform_Cleanup, - .pfnEndOfStream = Gstreamer_transform_EndOfStream, - .pfnBeginFlush = Gstreamer_transform_BeginFlush, - .pfnEndFlush = Gstreamer_transform_EndFlush, - .pfnNewSegment = Gstreamer_transform_NewSegment, - .pfnNotify = Gstreamer_transform_QOS, -}; - -IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr) -{ - const char *plugin; - IUnknown *obj = NULL; - - TRACE("%p %p\n", punkouter, phr); - - if (!init_gstreamer()) - { - *phr = E_FAIL; - return NULL; - } - - mark_wine_thread(); - - plugin = Gstreamer_FindMatch("audio/mpeg, mpegversion=(int) 1"); - if (!plugin) - { - *phr = E_FAIL; - return NULL; - } - - *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_Mp3, plugin, &Gstreamer_Mp3_vtbl, (LPVOID*)&obj); - - TRACE("returning %p\n", obj); - - return obj; -} diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 3e0ef28afb6..59c2bd974d4 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -38,8 +38,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
static const WCHAR wGstreamer_Splitter[] = {'G','S','t','r','e','a','m','e','r',' ','s','p','l','i','t','t','e','r',' ','f','i','l','t','e','r',0}; -static const WCHAR wGstreamer_Mp3[] = -{'G','S','t','r','e','a','m','e','r',' ','M','p','3',' ','f','i','l','t','e','r',0}; static const WCHAR wave_parserW[] = {'W','a','v','e',' ','P','a','r','s','e','r',0}; static const WCHAR avi_splitterW[] = @@ -94,32 +92,6 @@ static const AMOVIESETUP_FILTER amfSplitter = amfSplitPin };
-AMOVIESETUP_PIN amfMp3Pin[] = -{ { wNull, - FALSE, FALSE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, - { - wNull, - FALSE, TRUE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, -}; - -AMOVIESETUP_FILTER const amfMp3 = -{ &CLSID_Gstreamer_Mp3, - wGstreamer_Mp3, - MERIT_NORMAL, - 2, - amfMp3Pin -}; - static const AMOVIESETUP_MEDIATYPE wave_parser_sink_type_data[] = { {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE}, @@ -260,13 +232,6 @@ FactoryTemplate const g_Templates[] = { NULL, &amfSplitter, }, - { - wGstreamer_Mp3, - &CLSID_Gstreamer_Mp3, - Gstreamer_Mp3_create, - NULL, - &amfMp3, - }, { wave_parserW, &CLSID_WAVEParser,