mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Re-enable mfplat-streaming-support
We had reverted the current upstream winegreamer commits to allow mfplat-streaming-support to be used within staging. Hopefully the patchset in question will be upstream shortly.
This commit is contained in:
parent
fdcc8bec48
commit
fc40539f6d
@ -0,0 +1,29 @@
|
||||
From 28339597a00da381c079c9d4f46b67780511c267 Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:07:56 +1000
|
||||
Subject: [PATCH 1/6] Revert "winegstreamer: Fix return code in init_gst
|
||||
failure case."
|
||||
|
||||
This reverts commit b9a7e961cdd39203866be38e90b1d901595d54ba.
|
||||
---
|
||||
dlls/winegstreamer/quartz_parser.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
|
||||
index a8e7e3d979f..5299f4dc2ed 100644
|
||||
--- a/dlls/winegstreamer/quartz_parser.c
|
||||
+++ b/dlls/winegstreamer/quartz_parser.c
|
||||
@@ -982,10 +982,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons
|
||||
goto err;
|
||||
|
||||
if (!filter->init_gst(filter))
|
||||
- {
|
||||
- hr = E_FAIL;
|
||||
goto err;
|
||||
- }
|
||||
|
||||
for (i = 0; i < filter->source_count; ++i)
|
||||
{
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,614 @@
|
||||
From 1106d6f409e0876e72c73d71982519f5e6d7e1c5 Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:08:01 +1000
|
||||
Subject: [PATCH 2/6] Revert "winegstreamer: Replace source pad interface with
|
||||
GstAppSrc."
|
||||
|
||||
This reverts commit 1aa359a100bae859b278007e8bf90673eebd7db0.
|
||||
---
|
||||
dlls/winegstreamer/wg_parser.c | 425 ++++++++++++++++++++++++---------
|
||||
1 file changed, 308 insertions(+), 117 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
|
||||
index 6b6b033b879..f0815e37689 100644
|
||||
--- a/dlls/winegstreamer/wg_parser.c
|
||||
+++ b/dlls/winegstreamer/wg_parser.c
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/audio/audio.h>
|
||||
-#include <gst/app/gstappsrc.h>
|
||||
|
||||
/* GStreamer callbacks may be called on threads not created by Wine, and
|
||||
* therefore cannot access the Wine TEB. This means that we must use GStreamer
|
||||
@@ -50,20 +49,28 @@ struct wg_parser
|
||||
struct wg_parser_stream **streams;
|
||||
unsigned int stream_count;
|
||||
|
||||
- GstElement *container, *appsrc, *decodebin;
|
||||
+ GstElement *container, *decodebin;
|
||||
GstBus *bus;
|
||||
+ GstPad *my_src, *their_sink;
|
||||
+
|
||||
+ guint64 file_size, start_offset, next_offset, stop_offset;
|
||||
+ guint64 next_pull_offset;
|
||||
+
|
||||
+ pthread_t push_thread;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
pthread_cond_t init_cond;
|
||||
bool no_more_pads, has_duration, error;
|
||||
|
||||
- pthread_cond_t read_cond;
|
||||
+ pthread_cond_t read_cond, read_done_cond;
|
||||
struct
|
||||
{
|
||||
+ void *data;
|
||||
uint64_t offset;
|
||||
uint32_t size;
|
||||
- bool pending;
|
||||
+ bool done;
|
||||
+ bool ret;
|
||||
} read_request;
|
||||
|
||||
bool flushing, sink_connected;
|
||||
@@ -515,7 +522,7 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
|
||||
{
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
- while (parser->sink_connected && !parser->read_request.pending)
|
||||
+ while (parser->sink_connected && !parser->read_request.data)
|
||||
pthread_cond_wait(&parser->read_cond, &parser->mutex);
|
||||
|
||||
if (!parser->sink_connected)
|
||||
@@ -534,69 +541,15 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
|
||||
static void CDECL wg_parser_push_data(struct wg_parser *parser,
|
||||
const void *data, uint32_t size)
|
||||
{
|
||||
- GstMessage *message;
|
||||
- GstFlowReturn ret;
|
||||
- GstBuffer *buffer;
|
||||
- GError *error;
|
||||
-
|
||||
- if (!data)
|
||||
- {
|
||||
- pthread_mutex_lock(&parser->mutex);
|
||||
-
|
||||
- if (parser->sink_connected)
|
||||
- {
|
||||
- error = g_error_new(G_FILE_ERROR, G_FILE_ERROR_FAILED, "WG-Parser client failed to read data at offset %" G_GUINT64_FORMAT, parser->read_request.offset);
|
||||
- message = gst_message_new_error(NULL, error, "");
|
||||
- gst_bus_post(parser->bus, message);
|
||||
- parser->read_request.pending = false;
|
||||
- }
|
||||
-
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (!size)
|
||||
- {
|
||||
- pthread_mutex_lock(&parser->mutex);
|
||||
-
|
||||
- if (parser->sink_connected)
|
||||
- g_signal_emit_by_name(G_OBJECT(parser->appsrc), "end-of-stream", &ret);
|
||||
- parser->read_request.pending = false;
|
||||
-
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* We will always perform an extra blit here. We can avoid this in some
|
||||
- * cases by wrapping a client-allocated buffer using
|
||||
- * gst_buffer_new_wrapped(). However, releasing the memory is non-trivial,
|
||||
- * since GStreamer will hold onto a reference for an arbitrarily long
|
||||
- * period of time. Until there's evidence to suggest that the blit causes a
|
||||
- * performance problem, leave it alone. */
|
||||
- buffer = gst_buffer_new_and_alloc(size);
|
||||
- gst_buffer_fill(buffer, 0, data, size);
|
||||
-
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
-
|
||||
- if (!parser->sink_connected)
|
||||
- {
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- gst_buffer_unref(buffer);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- assert(parser->read_request.pending);
|
||||
-
|
||||
- GST_BUFFER_OFFSET(buffer) = parser->read_request.offset;
|
||||
- g_signal_emit_by_name(G_OBJECT(parser->appsrc), "push-buffer", buffer, &ret);
|
||||
-
|
||||
- /* In random-access mode, GST_FLOW_EOS shouldn't be returned. */
|
||||
- assert(ret == GST_FLOW_OK || ret == GST_FLOW_FLUSHING);
|
||||
- if (ret == GST_FLOW_OK)
|
||||
- parser->read_request.offset += size;
|
||||
-
|
||||
- parser->read_request.pending = false;
|
||||
+ parser->read_request.size = size;
|
||||
+ parser->read_request.done = true;
|
||||
+ parser->read_request.ret = !!data;
|
||||
+ if (data)
|
||||
+ memcpy(parser->read_request.data, data, size);
|
||||
+ parser->read_request.data = NULL;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
+ pthread_cond_signal(&parser->read_done_cond);
|
||||
}
|
||||
|
||||
static void CDECL wg_parser_set_unlimited_buffering(struct wg_parser *parser)
|
||||
@@ -1251,56 +1204,196 @@ static void pad_removed_cb(GstElement *element, GstPad *pad, gpointer user)
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
-static void src_need_data(GstElement *appsrc, guint length, gpointer user)
|
||||
+static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
|
||||
+ guint64 offset, guint size, GstBuffer **buffer)
|
||||
{
|
||||
- struct wg_parser *parser = user;
|
||||
- guint64 queued_bytes;
|
||||
+ struct wg_parser *parser = gst_pad_get_element_private(pad);
|
||||
+ GstBuffer *new_buffer = NULL;
|
||||
+ GstMapInfo map_info;
|
||||
+ bool ret;
|
||||
+
|
||||
+ GST_LOG("pad %p, offset %" G_GINT64_MODIFIER "u, length %u, buffer %p.", pad, offset, size, *buffer);
|
||||
+
|
||||
+ if (offset == GST_BUFFER_OFFSET_NONE)
|
||||
+ offset = parser->next_pull_offset;
|
||||
+ parser->next_pull_offset = offset + size;
|
||||
+
|
||||
+ if (!*buffer)
|
||||
+ *buffer = new_buffer = gst_buffer_new_and_alloc(size);
|
||||
+
|
||||
+ gst_buffer_map(*buffer, &map_info, GST_MAP_WRITE);
|
||||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
- /* As of GStreamer 1.18, appsrc suffers from a race condition. When in
|
||||
- * random access mode (and when underlyingly in pull mode), appsrc may
|
||||
- * spuriously send multiple requests for the same offset and length. If it
|
||||
- * receives the same buffer twice (or consecutive buffers), it will blindly
|
||||
- * queue them and satisfy subsequent getrange requests from downstream
|
||||
- * elements with the wrong buffers.
|
||||
- *
|
||||
- * Internally, this function is called inside of a loop, which also pops
|
||||
- * buffers from the internal queue. Accordingly we can safely treat this
|
||||
- * request as spurious by checking if we have already sent data; since the
|
||||
- * data is consumed by this thread it will not have been consumed yet.
|
||||
- *
|
||||
- * The bug is documented in greater detail here:
|
||||
- *
|
||||
- * https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/937
|
||||
- */
|
||||
- g_object_get(G_OBJECT(appsrc), "current-level-bytes", &queued_bytes, NULL);
|
||||
- if (queued_bytes)
|
||||
+ assert(!parser->read_request.data);
|
||||
+ parser->read_request.data = map_info.data;
|
||||
+ parser->read_request.offset = offset;
|
||||
+ parser->read_request.size = size;
|
||||
+ parser->read_request.done = false;
|
||||
+ pthread_cond_signal(&parser->read_cond);
|
||||
+
|
||||
+ /* Note that we don't unblock this wait on GST_EVENT_FLUSH_START. We expect
|
||||
+ * the upstream pin to flush if necessary. We should never be blocked on
|
||||
+ * read_thread() not running. */
|
||||
+
|
||||
+ while (!parser->read_request.done)
|
||||
+ pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
|
||||
+
|
||||
+ ret = parser->read_request.ret;
|
||||
+ gst_buffer_set_size(*buffer, parser->read_request.size);
|
||||
+
|
||||
+ pthread_mutex_unlock(&parser->mutex);
|
||||
+
|
||||
+ gst_buffer_unmap(*buffer, &map_info);
|
||||
+
|
||||
+ GST_LOG("Request returned %d.", ret);
|
||||
+
|
||||
+ if ((!ret || !size) && new_buffer)
|
||||
+ gst_buffer_unref(new_buffer);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return size ? GST_FLOW_OK : GST_FLOW_EOS;
|
||||
+ return GST_FLOW_ERROR;
|
||||
+}
|
||||
+
|
||||
+static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||
+{
|
||||
+ struct wg_parser *parser = gst_pad_get_element_private(pad);
|
||||
+ GstFormat format;
|
||||
+
|
||||
+ GST_LOG("parser %p, type %s.", parser, GST_QUERY_TYPE_NAME(query));
|
||||
+
|
||||
+ switch (GST_QUERY_TYPE(query))
|
||||
{
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- return;
|
||||
+ case GST_QUERY_DURATION:
|
||||
+ gst_query_parse_duration(query, &format, NULL);
|
||||
+ if (format == GST_FORMAT_PERCENT)
|
||||
+ {
|
||||
+ gst_query_set_duration(query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ else if (format == GST_FORMAT_BYTES)
|
||||
+ {
|
||||
+ gst_query_set_duration(query, GST_FORMAT_BYTES, parser->file_size);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+
|
||||
+ case GST_QUERY_SEEKING:
|
||||
+ gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
|
||||
+ if (format != GST_FORMAT_BYTES)
|
||||
+ {
|
||||
+ GST_WARNING("Cannot seek using format \"%s\".", gst_format_get_name(format));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ gst_query_set_seeking(query, GST_FORMAT_BYTES, 1, 0, parser->file_size);
|
||||
+ return TRUE;
|
||||
+
|
||||
+ case GST_QUERY_SCHEDULING:
|
||||
+ gst_query_set_scheduling(query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0);
|
||||
+ gst_query_add_scheduling_mode(query, GST_PAD_MODE_PUSH);
|
||||
+ gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL);
|
||||
+ return TRUE;
|
||||
+
|
||||
+ default:
|
||||
+ GST_WARNING("Unhandled query type %s.", GST_QUERY_TYPE_NAME(query));
|
||||
+ return FALSE;
|
||||
}
|
||||
+}
|
||||
|
||||
- parser->read_request.pending = true;
|
||||
- parser->read_request.size = length;
|
||||
+static void *push_data(void *arg)
|
||||
+{
|
||||
+ struct wg_parser *parser = arg;
|
||||
+ GstBuffer *buffer;
|
||||
+ guint max_size;
|
||||
|
||||
- pthread_cond_signal(&parser->read_cond);
|
||||
+ GST_DEBUG("Starting push thread.");
|
||||
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
+ if (!(buffer = gst_buffer_new_allocate(NULL, 16384, NULL)))
|
||||
+ {
|
||||
+ GST_ERROR("Failed to allocate memory.");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ max_size = parser->stop_offset ? parser->stop_offset : parser->file_size;
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ ULONG size;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (parser->next_offset >= max_size)
|
||||
+ break;
|
||||
+ size = min(16384, max_size - parser->next_offset);
|
||||
+
|
||||
+ if ((ret = src_getrange_cb(parser->my_src, NULL, parser->next_offset, size, &buffer)) < 0)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to read data, ret %s.", gst_flow_get_name(ret));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ parser->next_offset += size;
|
||||
+
|
||||
+ buffer->duration = buffer->pts = -1;
|
||||
+ if ((ret = gst_pad_push(parser->my_src, buffer)) < 0)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to push data, ret %s.", gst_flow_get_name(ret));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ gst_buffer_unref(buffer);
|
||||
+
|
||||
+ gst_pad_push_event(parser->my_src, gst_event_new_eos());
|
||||
+
|
||||
+ GST_DEBUG("Stopping push thread.");
|
||||
+
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
-static gboolean src_seek_data(GstElement *appsrc, guint64 offset, gpointer user)
|
||||
+static gboolean activate_push(GstPad *pad, gboolean activate)
|
||||
{
|
||||
- struct wg_parser *parser = user;
|
||||
+ struct wg_parser *parser = gst_pad_get_element_private(pad);
|
||||
|
||||
- pthread_mutex_lock(&parser->mutex);
|
||||
+ if (!activate)
|
||||
+ {
|
||||
+ if (parser->push_thread)
|
||||
+ {
|
||||
+ pthread_join(parser->push_thread, NULL);
|
||||
+ parser->push_thread = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (!parser->push_thread)
|
||||
+ {
|
||||
+ int ret;
|
||||
|
||||
- assert(!parser->read_request.pending);
|
||||
- parser->read_request.offset = offset;
|
||||
+ if ((ret = pthread_create(&parser->push_thread, NULL, push_data, parser)))
|
||||
+ {
|
||||
+ GST_ERROR("Failed to create push thread: %s", strerror(errno));
|
||||
+ parser->push_thread = 0;
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
+static gboolean src_activate_mode_cb(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate)
|
||||
+{
|
||||
+ struct wg_parser *parser = gst_pad_get_element_private(pad);
|
||||
|
||||
- return true;
|
||||
+ GST_DEBUG("%s source pad for parser %p in %s mode.",
|
||||
+ activate ? "Activating" : "Deactivating", parser, gst_pad_mode_get_name(mode));
|
||||
+
|
||||
+ switch (mode)
|
||||
+ {
|
||||
+ case GST_PAD_MODE_PULL:
|
||||
+ return TRUE;
|
||||
+ case GST_PAD_MODE_PUSH:
|
||||
+ return activate_push(pad, activate);
|
||||
+ case GST_PAD_MODE_NONE:
|
||||
+ break;
|
||||
+ }
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer user)
|
||||
@@ -1347,11 +1440,89 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use
|
||||
return GST_BUS_DROP;
|
||||
}
|
||||
|
||||
+static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event)
|
||||
+{
|
||||
+ BOOL thread = !!parser->push_thread;
|
||||
+ GstSeekType cur_type, stop_type;
|
||||
+ GstFormat seek_format;
|
||||
+ GstEvent *flush_event;
|
||||
+ GstSeekFlags flags;
|
||||
+ gint64 cur, stop;
|
||||
+ guint32 seqnum;
|
||||
+ gdouble rate;
|
||||
+
|
||||
+ gst_event_parse_seek(event, &rate, &seek_format, &flags,
|
||||
+ &cur_type, &cur, &stop_type, &stop);
|
||||
+
|
||||
+ if (seek_format != GST_FORMAT_BYTES)
|
||||
+ {
|
||||
+ GST_FIXME("Unhandled format \"%s\".", gst_format_get_name(seek_format));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ seqnum = gst_event_get_seqnum(event);
|
||||
+
|
||||
+ /* send flush start */
|
||||
+ if (flags & GST_SEEK_FLAG_FLUSH)
|
||||
+ {
|
||||
+ flush_event = gst_event_new_flush_start();
|
||||
+ gst_event_set_seqnum(flush_event, seqnum);
|
||||
+ gst_pad_push_event(parser->my_src, flush_event);
|
||||
+ if (thread)
|
||||
+ gst_pad_set_active(parser->my_src, 1);
|
||||
+ }
|
||||
+
|
||||
+ parser->next_offset = parser->start_offset = cur;
|
||||
+
|
||||
+ /* and prepare to continue streaming */
|
||||
+ if (flags & GST_SEEK_FLAG_FLUSH)
|
||||
+ {
|
||||
+ flush_event = gst_event_new_flush_stop(TRUE);
|
||||
+ gst_event_set_seqnum(flush_event, seqnum);
|
||||
+ gst_pad_push_event(parser->my_src, flush_event);
|
||||
+ if (thread)
|
||||
+ gst_pad_set_active(parser->my_src, 1);
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
|
||||
+{
|
||||
+ struct wg_parser *parser = gst_pad_get_element_private(pad);
|
||||
+ gboolean ret = TRUE;
|
||||
+
|
||||
+ GST_LOG("parser %p, type \"%s\".", parser, GST_EVENT_TYPE_NAME(event));
|
||||
+
|
||||
+ switch (event->type)
|
||||
+ {
|
||||
+ case GST_EVENT_SEEK:
|
||||
+ ret = src_perform_seek(parser, event);
|
||||
+ break;
|
||||
+
|
||||
+ case GST_EVENT_FLUSH_START:
|
||||
+ case GST_EVENT_FLUSH_STOP:
|
||||
+ case GST_EVENT_QOS:
|
||||
+ case GST_EVENT_RECONFIGURE:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ GST_WARNING("Ignoring \"%s\" event.", GST_EVENT_TYPE_NAME(event));
|
||||
+ ret = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ gst_event_unref(event);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_size)
|
||||
{
|
||||
+ GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("quartz_src",
|
||||
+ GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
+ parser->file_size = file_size;
|
||||
parser->sink_connected = true;
|
||||
|
||||
if (!parser->bus)
|
||||
@@ -1363,16 +1534,15 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
parser->container = gst_bin_new(NULL);
|
||||
gst_element_set_bus(parser->container, parser->bus);
|
||||
|
||||
- if (!(parser->appsrc = create_element("appsrc", "base")))
|
||||
- return E_FAIL;
|
||||
- gst_bin_add(GST_BIN(parser->container), parser->appsrc);
|
||||
+ parser->my_src = gst_pad_new_from_static_template(&src_template, "quartz-src");
|
||||
+ gst_pad_set_getrange_function(parser->my_src, src_getrange_cb);
|
||||
+ gst_pad_set_query_function(parser->my_src, src_query_cb);
|
||||
+ gst_pad_set_activatemode_function(parser->my_src, src_activate_mode_cb);
|
||||
+ gst_pad_set_event_function(parser->my_src, src_event_cb);
|
||||
+ gst_pad_set_element_private(parser->my_src, parser);
|
||||
|
||||
- g_object_set(parser->appsrc, "stream-type", GST_APP_STREAM_TYPE_RANDOM_ACCESS, NULL);
|
||||
- g_object_set(parser->appsrc, "size", file_size, NULL);
|
||||
- g_signal_connect(parser->appsrc, "need-data", G_CALLBACK(src_need_data), parser);
|
||||
- g_signal_connect(parser->appsrc, "seek-data", G_CALLBACK(src_seek_data), parser);
|
||||
-
|
||||
- parser->read_request.offset = 0;
|
||||
+ parser->start_offset = parser->next_offset = parser->stop_offset = 0;
|
||||
+ parser->next_pull_offset = 0;
|
||||
parser->error = false;
|
||||
|
||||
if (!parser->init_gst(parser))
|
||||
@@ -1468,11 +1638,18 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
+ parser->next_offset = 0;
|
||||
return S_OK;
|
||||
|
||||
out:
|
||||
if (parser->container)
|
||||
gst_element_set_state(parser->container, GST_STATE_NULL);
|
||||
+ if (parser->their_sink)
|
||||
+ {
|
||||
+ gst_pad_unlink(parser->my_src, parser->their_sink);
|
||||
+ gst_object_unref(parser->their_sink);
|
||||
+ parser->my_src = parser->their_sink = NULL;
|
||||
+ }
|
||||
|
||||
for (i = 0; i < parser->stream_count; ++i)
|
||||
free_stream(parser->streams[i]);
|
||||
@@ -1509,6 +1686,10 @@ static void CDECL wg_parser_disconnect(struct wg_parser *parser)
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
gst_element_set_state(parser->container, GST_STATE_NULL);
|
||||
+ gst_pad_unlink(parser->my_src, parser->their_sink);
|
||||
+ gst_object_unref(parser->my_src);
|
||||
+ gst_object_unref(parser->their_sink);
|
||||
+ parser->my_src = parser->their_sink = NULL;
|
||||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
parser->sink_connected = false;
|
||||
@@ -1530,6 +1711,7 @@ static void CDECL wg_parser_disconnect(struct wg_parser *parser)
|
||||
static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
|
||||
{
|
||||
GstElement *element;
|
||||
+ int ret;
|
||||
|
||||
if (!(element = create_element("decodebin", "base")))
|
||||
return FALSE;
|
||||
@@ -1542,13 +1724,15 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
|
||||
g_signal_connect(element, "autoplug-select", G_CALLBACK(autoplug_select_cb), parser);
|
||||
g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser);
|
||||
|
||||
+ parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
+
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
parser->no_more_pads = false;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
- if (!gst_element_link(parser->appsrc, parser->decodebin))
|
||||
+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
{
|
||||
- GST_ERROR("Failed to link appsrc.\n");
|
||||
+ GST_ERROR("Failed to link pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1558,6 +1742,7 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
|
||||
static BOOL avi_parser_init_gst(struct wg_parser *parser)
|
||||
{
|
||||
GstElement *element;
|
||||
+ int ret;
|
||||
|
||||
if (!(element = create_element("avidemux", "good")))
|
||||
return FALSE;
|
||||
@@ -1568,13 +1753,15 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser)
|
||||
g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser);
|
||||
g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser);
|
||||
|
||||
+ parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
+
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
parser->no_more_pads = false;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
- if (!gst_element_link(parser->appsrc, element))
|
||||
+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
{
|
||||
- GST_ERROR("Failed to link appsrc.\n");
|
||||
+ GST_ERROR("Failed to link pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1592,9 +1779,10 @@ static BOOL mpeg_audio_parser_init_gst(struct wg_parser *parser)
|
||||
|
||||
gst_bin_add(GST_BIN(parser->container), element);
|
||||
|
||||
- if (!gst_element_link(parser->appsrc, element))
|
||||
+ parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
{
|
||||
- GST_ERROR("Failed to link appsrc.\n");
|
||||
+ GST_ERROR("Failed to link sink pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1625,9 +1813,10 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser)
|
||||
|
||||
gst_bin_add(GST_BIN(parser->container), element);
|
||||
|
||||
- if (!gst_element_link(parser->appsrc, element))
|
||||
+ parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
{
|
||||
- GST_ERROR("Failed to link appsrc.\n");
|
||||
+ GST_ERROR("Failed to link sink pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1658,6 +1847,7 @@ static struct wg_parser *wg_parser_create(void)
|
||||
pthread_mutex_init(&parser->mutex, NULL);
|
||||
pthread_cond_init(&parser->init_cond, NULL);
|
||||
pthread_cond_init(&parser->read_cond, NULL);
|
||||
+ pthread_cond_init(&parser->read_done_cond, NULL);
|
||||
parser->flushing = true;
|
||||
|
||||
GST_DEBUG("Created winegstreamer parser %p.\n", parser);
|
||||
@@ -1711,6 +1901,7 @@ static void CDECL wg_parser_destroy(struct wg_parser *parser)
|
||||
pthread_mutex_destroy(&parser->mutex);
|
||||
pthread_cond_destroy(&parser->init_cond);
|
||||
pthread_cond_destroy(&parser->read_cond);
|
||||
+ pthread_cond_destroy(&parser->read_done_cond);
|
||||
|
||||
free(parser);
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,224 @@
|
||||
From 2e341e32dd761e40c9045648b0edfabd9b49fc4e Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:08:02 +1000
|
||||
Subject: [PATCH 3/6] Revert "winegstreamer: Allocate source media buffers in
|
||||
the PE components."
|
||||
|
||||
This reverts commit 8b7390f80d866435f06f2571a93bcd67c0947673.
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 7 +++----
|
||||
dlls/winegstreamer/media_source.c | 28 ++++------------------------
|
||||
dlls/winegstreamer/quartz_parser.c | 26 +++-----------------------
|
||||
dlls/winegstreamer/wg_parser.c | 28 +++++++++++++---------------
|
||||
4 files changed, 23 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 49e06b31369..c29fc4a2437 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -170,10 +170,9 @@ struct unix_funcs
|
||||
void (CDECL *wg_parser_begin_flush)(struct wg_parser *parser);
|
||||
void (CDECL *wg_parser_end_flush)(struct wg_parser *parser);
|
||||
|
||||
- bool (CDECL *wg_parser_get_next_read_offset)(struct wg_parser *parser,
|
||||
- uint64_t *offset, uint32_t *size);
|
||||
- void (CDECL *wg_parser_push_data)(struct wg_parser *parser,
|
||||
- const void *data, uint32_t size);
|
||||
+ bool (CDECL *wg_parser_get_read_request)(struct wg_parser *parser,
|
||||
+ void **data, uint64_t *offset, uint32_t *size);
|
||||
+ void (CDECL *wg_parser_complete_read_request)(struct wg_parser *parser, bool ret);
|
||||
|
||||
void (CDECL *wg_parser_set_unlimited_buffering)(struct wg_parser *parser);
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 825bad8da27..95bdb9b488e 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -530,11 +530,6 @@ static DWORD CALLBACK read_thread(void *arg)
|
||||
{
|
||||
struct media_source *source = arg;
|
||||
IMFByteStream *byte_stream = source->byte_stream;
|
||||
- uint32_t buffer_size = 0;
|
||||
- uint64_t file_size;
|
||||
- void *data = NULL;
|
||||
-
|
||||
- IMFByteStream_GetLength(byte_stream, &file_size);
|
||||
|
||||
TRACE("Starting read thread for media source %p.\n", source);
|
||||
|
||||
@@ -544,33 +539,18 @@ static DWORD CALLBACK read_thread(void *arg)
|
||||
ULONG ret_size;
|
||||
uint32_t size;
|
||||
HRESULT hr;
|
||||
+ void *data;
|
||||
|
||||
- if (!unix_funcs->wg_parser_get_next_read_offset(source->wg_parser, &offset, &size))
|
||||
+ if (!unix_funcs->wg_parser_get_read_request(source->wg_parser, &data, &offset, &size))
|
||||
continue;
|
||||
|
||||
- if (offset >= file_size)
|
||||
- size = 0;
|
||||
- else if (offset + size >= file_size)
|
||||
- size = file_size - offset;
|
||||
-
|
||||
- if (size > buffer_size)
|
||||
- {
|
||||
- buffer_size = size;
|
||||
- data = realloc(data, size);
|
||||
- }
|
||||
-
|
||||
- ret_size = 0;
|
||||
-
|
||||
if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset)))
|
||||
hr = IMFByteStream_Read(byte_stream, data, size, &ret_size);
|
||||
- if (FAILED(hr))
|
||||
- ERR("Failed to read %u bytes at offset %I64u, hr %#x.\n", size, offset, hr);
|
||||
- else if (ret_size != size)
|
||||
+ if (SUCCEEDED(hr) && ret_size != size)
|
||||
ERR("Unexpected short read: requested %u bytes, got %u.\n", size, ret_size);
|
||||
- unix_funcs->wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size);
|
||||
+ unix_funcs->wg_parser_complete_read_request(source->wg_parser, SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
- free(data);
|
||||
TRACE("Media source is shutting down; exiting.\n");
|
||||
return 0;
|
||||
}
|
||||
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
|
||||
index 5299f4dc2ed..09a916d7f5c 100644
|
||||
--- a/dlls/winegstreamer/quartz_parser.c
|
||||
+++ b/dlls/winegstreamer/quartz_parser.c
|
||||
@@ -785,11 +785,6 @@ static DWORD CALLBACK stream_thread(void *arg)
|
||||
static DWORD CALLBACK read_thread(void *arg)
|
||||
{
|
||||
struct parser *filter = arg;
|
||||
- LONGLONG file_size, unused;
|
||||
- uint32_t buffer_size = 0;
|
||||
- void *data = NULL;
|
||||
-
|
||||
- IAsyncReader_Length(filter->reader, &file_size, &unused);
|
||||
|
||||
TRACE("Starting read thread for filter %p.\n", filter);
|
||||
|
||||
@@ -798,29 +793,14 @@ static DWORD CALLBACK read_thread(void *arg)
|
||||
uint64_t offset;
|
||||
uint32_t size;
|
||||
HRESULT hr;
|
||||
+ void *data;
|
||||
|
||||
- if (!unix_funcs->wg_parser_get_next_read_offset(filter->wg_parser, &offset, &size))
|
||||
+ if (!unix_funcs->wg_parser_get_read_request(filter->wg_parser, &data, &offset, &size))
|
||||
continue;
|
||||
-
|
||||
- if (offset >= file_size)
|
||||
- size = 0;
|
||||
- else if (offset + size >= file_size)
|
||||
- size = file_size - offset;
|
||||
-
|
||||
- if (size > buffer_size)
|
||||
- {
|
||||
- buffer_size = size;
|
||||
- data = realloc(data, size);
|
||||
- }
|
||||
-
|
||||
hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);
|
||||
- if (FAILED(hr))
|
||||
- ERR("Failed to read %u bytes at offset %I64u, hr %#x.\n", size, offset, hr);
|
||||
-
|
||||
- unix_funcs->wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size);
|
||||
+ unix_funcs->wg_parser_complete_read_request(filter->wg_parser, SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
- free(data);
|
||||
TRACE("Streaming stopped; exiting.\n");
|
||||
return 0;
|
||||
}
|
||||
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
|
||||
index f0815e37689..119cbffbd88 100644
|
||||
--- a/dlls/winegstreamer/wg_parser.c
|
||||
+++ b/dlls/winegstreamer/wg_parser.c
|
||||
@@ -517,8 +517,8 @@ static void CDECL wg_parser_end_flush(struct wg_parser *parser)
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
}
|
||||
|
||||
-static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
|
||||
- uint64_t *offset, uint32_t *size)
|
||||
+static bool CDECL wg_parser_get_read_request(struct wg_parser *parser,
|
||||
+ void **data, uint64_t *offset, uint32_t *size)
|
||||
{
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
@@ -531,6 +531,7 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ *data = parser->read_request.data;
|
||||
*offset = parser->read_request.offset;
|
||||
*size = parser->read_request.size;
|
||||
|
||||
@@ -538,15 +539,11 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
|
||||
return true;
|
||||
}
|
||||
|
||||
-static void CDECL wg_parser_push_data(struct wg_parser *parser,
|
||||
- const void *data, uint32_t size)
|
||||
+static void CDECL wg_parser_complete_read_request(struct wg_parser *parser, bool ret)
|
||||
{
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
- parser->read_request.size = size;
|
||||
parser->read_request.done = true;
|
||||
- parser->read_request.ret = !!data;
|
||||
- if (data)
|
||||
- memcpy(parser->read_request.data, data, size);
|
||||
+ parser->read_request.ret = ret;
|
||||
parser->read_request.data = NULL;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
pthread_cond_signal(&parser->read_done_cond);
|
||||
@@ -1217,6 +1214,10 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
|
||||
if (offset == GST_BUFFER_OFFSET_NONE)
|
||||
offset = parser->next_pull_offset;
|
||||
parser->next_pull_offset = offset + size;
|
||||
+ if (offset >= parser->file_size)
|
||||
+ return GST_FLOW_EOS;
|
||||
+ if (offset + size >= parser->file_size)
|
||||
+ size = parser->file_size - offset;
|
||||
|
||||
if (!*buffer)
|
||||
*buffer = new_buffer = gst_buffer_new_and_alloc(size);
|
||||
@@ -1240,7 +1241,6 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
|
||||
pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
|
||||
|
||||
ret = parser->read_request.ret;
|
||||
- gst_buffer_set_size(*buffer, parser->read_request.size);
|
||||
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
@@ -1248,12 +1248,10 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
|
||||
|
||||
GST_LOG("Request returned %d.", ret);
|
||||
|
||||
- if ((!ret || !size) && new_buffer)
|
||||
+ if (!ret && new_buffer)
|
||||
gst_buffer_unref(new_buffer);
|
||||
|
||||
- if (ret)
|
||||
- return size ? GST_FLOW_OK : GST_FLOW_EOS;
|
||||
- return GST_FLOW_ERROR;
|
||||
+ return ret ? GST_FLOW_OK : GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||
@@ -1920,8 +1918,8 @@ static const struct unix_funcs funcs =
|
||||
wg_parser_begin_flush,
|
||||
wg_parser_end_flush,
|
||||
|
||||
- wg_parser_get_next_read_offset,
|
||||
- wg_parser_push_data,
|
||||
+ wg_parser_get_read_request,
|
||||
+ wg_parser_complete_read_request,
|
||||
|
||||
wg_parser_set_unlimited_buffering,
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,221 @@
|
||||
From ca25389c3980c848dc6094f84160079a4cf805f7 Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:08:03 +1000
|
||||
Subject: [PATCH 4/6] Revert "winegstreamer: Duplicate source shutdown path
|
||||
into constructor with leak fixes."
|
||||
|
||||
This reverts commit 67734bfce31d6032cee1a8980a9022665e9e18fa.
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 -
|
||||
dlls/winegstreamer/media_source.c | 102 +++++++++++-------------------
|
||||
2 files changed, 37 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index c29fc4a2437..c6c99b1dd55 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -22,7 +22,6 @@
|
||||
#define __GST_PRIVATE_INCLUDED__
|
||||
|
||||
#include <assert.h>
|
||||
-#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 95bdb9b488e..01ab626254a 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -733,12 +733,6 @@ static HRESULT new_media_stream(struct media_source *source,
|
||||
object->IMFMediaStream_iface.lpVtbl = &media_stream_vtbl;
|
||||
object->ref = 1;
|
||||
|
||||
- if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
||||
- {
|
||||
- free(object);
|
||||
- return hr;
|
||||
- }
|
||||
-
|
||||
IMFMediaSource_AddRef(&source->IMFMediaSource_iface);
|
||||
object->parent_source = source;
|
||||
object->stream_id = stream_id;
|
||||
@@ -747,11 +741,20 @@ static HRESULT new_media_stream(struct media_source *source,
|
||||
object->eos = FALSE;
|
||||
object->wg_stream = wg_stream;
|
||||
|
||||
+ if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
||||
+ goto fail;
|
||||
+
|
||||
TRACE("Created stream object %p.\n", object);
|
||||
|
||||
*out_stream = object;
|
||||
|
||||
return S_OK;
|
||||
+
|
||||
+fail:
|
||||
+ WARN("Failed to construct media stream, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFMediaStream_Release(&object->IMFMediaStream_iface);
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
@@ -844,16 +847,10 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
goto done;
|
||||
|
||||
if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
|
||||
- {
|
||||
- IMFStreamDescriptor_Release(stream->descriptor);
|
||||
goto done;
|
||||
- }
|
||||
|
||||
if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_types[0])))
|
||||
- {
|
||||
- IMFStreamDescriptor_Release(stream->descriptor);
|
||||
goto done;
|
||||
- }
|
||||
|
||||
done:
|
||||
if (type_handler)
|
||||
@@ -1216,13 +1213,19 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
|
||||
unix_funcs->wg_parser_disconnect(source->wg_parser);
|
||||
|
||||
- source->read_thread_shutdown = true;
|
||||
- WaitForSingleObject(source->read_thread, INFINITE);
|
||||
- CloseHandle(source->read_thread);
|
||||
+ if (source->read_thread)
|
||||
+ {
|
||||
+ source->read_thread_shutdown = true;
|
||||
+ WaitForSingleObject(source->read_thread, INFINITE);
|
||||
+ CloseHandle(source->read_thread);
|
||||
+ }
|
||||
|
||||
- IMFPresentationDescriptor_Release(source->pres_desc);
|
||||
- IMFMediaEventQueue_Shutdown(source->event_queue);
|
||||
- IMFByteStream_Release(source->byte_stream);
|
||||
+ if (source->pres_desc)
|
||||
+ IMFPresentationDescriptor_Release(source->pres_desc);
|
||||
+ if (source->event_queue)
|
||||
+ IMFMediaEventQueue_Shutdown(source->event_queue);
|
||||
+ if (source->byte_stream)
|
||||
+ IMFByteStream_Release(source->byte_stream);
|
||||
|
||||
for (i = 0; i < source->stream_count; i++)
|
||||
{
|
||||
@@ -1230,18 +1233,23 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
|
||||
stream->state = STREAM_SHUTDOWN;
|
||||
|
||||
- IMFMediaEventQueue_Shutdown(stream->event_queue);
|
||||
- IMFStreamDescriptor_Release(stream->descriptor);
|
||||
- IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface);
|
||||
+ if (stream->event_queue)
|
||||
+ IMFMediaEventQueue_Shutdown(stream->event_queue);
|
||||
+ if (stream->descriptor)
|
||||
+ IMFStreamDescriptor_Release(stream->descriptor);
|
||||
+ if (stream->parent_source)
|
||||
+ IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface);
|
||||
|
||||
IMFMediaStream_Release(&stream->IMFMediaStream_iface);
|
||||
}
|
||||
|
||||
unix_funcs->wg_parser_destroy(source->wg_parser);
|
||||
|
||||
- free(source->streams);
|
||||
+ if (source->stream_count)
|
||||
+ free(source->streams);
|
||||
|
||||
- MFUnlockWorkQueue(source->async_commands_queue);
|
||||
+ if (source->async_commands_queue)
|
||||
+ MFUnlockWorkQueue(source->async_commands_queue);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1266,7 +1274,6 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source)
|
||||
{
|
||||
IMFStreamDescriptor **descriptors = NULL;
|
||||
- unsigned int stream_count = UINT_MAX;
|
||||
struct media_source *object;
|
||||
UINT64 total_pres_time = 0;
|
||||
struct wg_parser *parser;
|
||||
@@ -1330,15 +1337,15 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
* leak occurs with native. */
|
||||
unix_funcs->wg_parser_set_unlimited_buffering(parser);
|
||||
|
||||
- stream_count = unix_funcs->wg_parser_get_stream_count(parser);
|
||||
+ object->stream_count = unix_funcs->wg_parser_get_stream_count(parser);
|
||||
|
||||
- if (!(object->streams = calloc(stream_count, sizeof(*object->streams))))
|
||||
+ if (!(object->streams = calloc(object->stream_count, sizeof(*object->streams))))
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- for (i = 0; i < stream_count; ++i)
|
||||
+ for (i = 0; i < object->stream_count; ++i)
|
||||
{
|
||||
if (FAILED(hr = new_media_stream(object, unix_funcs->wg_parser_get_stream(parser, i), i, &object->streams[i])))
|
||||
goto fail;
|
||||
@@ -1346,13 +1353,9 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
if (FAILED(hr = media_stream_init_desc(object->streams[i])))
|
||||
{
|
||||
ERR("Failed to finish initialization of media stream %p, hr %x.\n", object->streams[i], hr);
|
||||
- IMFMediaSource_Release(&object->streams[i]->parent_source->IMFMediaSource_iface);
|
||||
- IMFMediaEventQueue_Release(object->streams[i]->event_queue);
|
||||
- free(object->streams[i]);
|
||||
+ IMFMediaStream_Release(&object->streams[i]->IMFMediaStream_iface);
|
||||
goto fail;
|
||||
}
|
||||
-
|
||||
- object->stream_count++;
|
||||
}
|
||||
|
||||
/* init presentation descriptor */
|
||||
@@ -1389,39 +1392,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
fail:
|
||||
WARN("Failed to construct MFMediaSource, hr %#x.\n", hr);
|
||||
|
||||
- if (descriptors)
|
||||
- {
|
||||
- for (i = 0; i < object->stream_count; i++)
|
||||
- IMFStreamDescriptor_Release(descriptors[i]);
|
||||
- free(descriptors);
|
||||
- }
|
||||
- for (i = 0; i < object->stream_count; i++)
|
||||
- {
|
||||
- struct media_stream *stream = object->streams[i];
|
||||
-
|
||||
- IMFMediaEventQueue_Release(stream->event_queue);
|
||||
- IMFStreamDescriptor_Release(stream->descriptor);
|
||||
- IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface);
|
||||
-
|
||||
- free(stream);
|
||||
- }
|
||||
- free(object->streams);
|
||||
- if (stream_count != UINT_MAX)
|
||||
- unix_funcs->wg_parser_disconnect(object->wg_parser);
|
||||
- if (object->read_thread)
|
||||
- {
|
||||
- object->read_thread_shutdown = true;
|
||||
- WaitForSingleObject(object->read_thread, INFINITE);
|
||||
- CloseHandle(object->read_thread);
|
||||
- }
|
||||
- if (object->wg_parser)
|
||||
- unix_funcs->wg_parser_destroy(object->wg_parser);
|
||||
- if (object->async_commands_queue)
|
||||
- MFUnlockWorkQueue(object->async_commands_queue);
|
||||
- if (object->event_queue)
|
||||
- IMFMediaEventQueue_Release(object->event_queue);
|
||||
- IMFByteStream_Release(object->byte_stream);
|
||||
- free(object);
|
||||
+ free(descriptors);
|
||||
+ IMFMediaSource_Release(&object->IMFMediaSource_iface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,140 @@
|
||||
From e648d762c2609321822334a9a8db8a2f5905b51d Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:08:04 +1000
|
||||
Subject: [PATCH 5/6] Revert "winegstreamer: Properly clean up from failure in
|
||||
wg_parser_connect()."
|
||||
|
||||
This reverts commit 721b1eb2ebe5c3eaab8ac3fb1e4f4648cbee5b4d.
|
||||
---
|
||||
dlls/winegstreamer/wg_parser.c | 76 ++++++++++------------------------
|
||||
1 file changed, 23 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
|
||||
index 119cbffbd88..bf5a51aeaf4 100644
|
||||
--- a/dlls/winegstreamer/wg_parser.c
|
||||
+++ b/dlls/winegstreamer/wg_parser.c
|
||||
@@ -1034,30 +1034,6 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser)
|
||||
return stream;
|
||||
}
|
||||
|
||||
-static void free_stream(struct wg_parser_stream *stream)
|
||||
-{
|
||||
- if (stream->their_src)
|
||||
- {
|
||||
- if (stream->post_sink)
|
||||
- {
|
||||
- gst_pad_unlink(stream->their_src, stream->post_sink);
|
||||
- gst_pad_unlink(stream->post_src, stream->my_sink);
|
||||
- gst_object_unref(stream->post_src);
|
||||
- gst_object_unref(stream->post_sink);
|
||||
- stream->post_src = stream->post_sink = NULL;
|
||||
- }
|
||||
- else
|
||||
- gst_pad_unlink(stream->their_src, stream->my_sink);
|
||||
- gst_object_unref(stream->their_src);
|
||||
- }
|
||||
- gst_object_unref(stream->my_sink);
|
||||
-
|
||||
- pthread_cond_destroy(&stream->event_cond);
|
||||
- pthread_cond_destroy(&stream->event_empty_cond);
|
||||
-
|
||||
- free(stream);
|
||||
-}
|
||||
-
|
||||
static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct wg_parser *parser = user;
|
||||
@@ -1544,14 +1520,14 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
parser->error = false;
|
||||
|
||||
if (!parser->init_gst(parser))
|
||||
- goto out;
|
||||
+ return E_FAIL;
|
||||
|
||||
gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
{
|
||||
GST_ERROR("Failed to play stream.\n");
|
||||
- goto out;
|
||||
+ return E_FAIL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
@@ -1561,7 +1537,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
if (parser->error)
|
||||
{
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
- goto out;
|
||||
+ return E_FAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < parser->stream_count; ++i)
|
||||
@@ -1601,7 +1577,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
if (parser->error)
|
||||
{
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
- goto out;
|
||||
+ return E_FAIL;
|
||||
}
|
||||
if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
|
||||
{
|
||||
@@ -1638,36 +1614,30 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
|
||||
parser->next_offset = 0;
|
||||
return S_OK;
|
||||
+}
|
||||
|
||||
-out:
|
||||
- if (parser->container)
|
||||
- gst_element_set_state(parser->container, GST_STATE_NULL);
|
||||
- if (parser->their_sink)
|
||||
- {
|
||||
- gst_pad_unlink(parser->my_src, parser->their_sink);
|
||||
- gst_object_unref(parser->their_sink);
|
||||
- parser->my_src = parser->their_sink = NULL;
|
||||
- }
|
||||
-
|
||||
- for (i = 0; i < parser->stream_count; ++i)
|
||||
- free_stream(parser->streams[i]);
|
||||
- parser->stream_count = 0;
|
||||
- free(parser->streams);
|
||||
- parser->streams = NULL;
|
||||
-
|
||||
- if (parser->container)
|
||||
+static void free_stream(struct wg_parser_stream *stream)
|
||||
+{
|
||||
+ if (stream->their_src)
|
||||
{
|
||||
- gst_element_set_bus(parser->container, NULL);
|
||||
- gst_object_unref(parser->container);
|
||||
- parser->container = NULL;
|
||||
+ if (stream->post_sink)
|
||||
+ {
|
||||
+ gst_pad_unlink(stream->their_src, stream->post_sink);
|
||||
+ gst_pad_unlink(stream->post_src, stream->my_sink);
|
||||
+ gst_object_unref(stream->post_src);
|
||||
+ gst_object_unref(stream->post_sink);
|
||||
+ stream->post_src = stream->post_sink = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ gst_pad_unlink(stream->their_src, stream->my_sink);
|
||||
+ gst_object_unref(stream->their_src);
|
||||
}
|
||||
+ gst_object_unref(stream->my_sink);
|
||||
|
||||
- pthread_mutex_lock(&parser->mutex);
|
||||
- parser->sink_connected = false;
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- pthread_cond_signal(&parser->read_cond);
|
||||
+ pthread_cond_destroy(&stream->event_cond);
|
||||
+ pthread_cond_destroy(&stream->event_empty_cond);
|
||||
|
||||
- return E_FAIL;
|
||||
+ free(stream);
|
||||
}
|
||||
|
||||
static void CDECL wg_parser_disconnect(struct wg_parser *parser)
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,160 @@
|
||||
From 6d496c2655531790cdfdb5869fd37b64ae405b8a Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Sun, 19 Sep 2021 13:08:05 +1000
|
||||
Subject: [PATCH 6/6] Revert "winegstreamer: Factor out more of the init_gst
|
||||
callback into wg_parser_connect()."
|
||||
|
||||
This reverts commit 830efe873a967dbbb0c9a65be6a66b124a5fa826.
|
||||
---
|
||||
dlls/winegstreamer/wg_parser.c | 78 +++++++++++++++++++++++-----------
|
||||
1 file changed, 54 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
|
||||
index bf5a51aeaf4..cd12a23d0c8 100644
|
||||
--- a/dlls/winegstreamer/wg_parser.c
|
||||
+++ b/dlls/winegstreamer/wg_parser.c
|
||||
@@ -1494,7 +1494,6 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("quartz_src",
|
||||
GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
|
||||
unsigned int i;
|
||||
- int ret;
|
||||
|
||||
parser->file_size = file_size;
|
||||
parser->sink_connected = true;
|
||||
@@ -1517,29 +1516,12 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||
|
||||
parser->start_offset = parser->next_offset = parser->stop_offset = 0;
|
||||
parser->next_pull_offset = 0;
|
||||
- parser->error = false;
|
||||
|
||||
if (!parser->init_gst(parser))
|
||||
return E_FAIL;
|
||||
|
||||
- gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
- ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
- if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
- {
|
||||
- GST_ERROR("Failed to play stream.\n");
|
||||
- return E_FAIL;
|
||||
- }
|
||||
-
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
- while (!parser->no_more_pads && !parser->error)
|
||||
- pthread_cond_wait(&parser->init_cond, &parser->mutex);
|
||||
- if (parser->error)
|
||||
- {
|
||||
- pthread_mutex_unlock(&parser->mutex);
|
||||
- return E_FAIL;
|
||||
- }
|
||||
-
|
||||
for (i = 0; i < parser->stream_count; ++i)
|
||||
{
|
||||
struct wg_parser_stream *stream = parser->streams[i];
|
||||
@@ -1695,7 +1677,7 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
|
||||
parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
- parser->no_more_pads = false;
|
||||
+ parser->no_more_pads = parser->error = false;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
@@ -1704,6 +1686,24 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
+ ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
+ if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to play stream.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ pthread_mutex_lock(&parser->mutex);
|
||||
+ while (!parser->no_more_pads && !parser->error)
|
||||
+ pthread_cond_wait(&parser->init_cond, &parser->mutex);
|
||||
+ if (parser->error)
|
||||
+ {
|
||||
+ pthread_mutex_unlock(&parser->mutex);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ pthread_mutex_unlock(&parser->mutex);
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1724,7 +1724,7 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser)
|
||||
parser->their_sink = gst_element_get_static_pad(element, "sink");
|
||||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
- parser->no_more_pads = false;
|
||||
+ parser->no_more_pads = parser->error = false;
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
||||
if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
|
||||
@@ -1733,6 +1733,24 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
+ ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
+ if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to play stream.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ pthread_mutex_lock(&parser->mutex);
|
||||
+ while (!parser->no_more_pads && !parser->error)
|
||||
+ pthread_cond_wait(&parser->init_cond, &parser->mutex);
|
||||
+ if (parser->error)
|
||||
+ {
|
||||
+ pthread_mutex_unlock(&parser->mutex);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ pthread_mutex_unlock(&parser->mutex);
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1763,9 +1781,15 @@ static BOOL mpeg_audio_parser_init_gst(struct wg_parser *parser)
|
||||
GST_ERROR("Failed to link source pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
- gst_pad_set_active(stream->my_sink, 1);
|
||||
|
||||
- parser->no_more_pads = true;
|
||||
+ gst_pad_set_active(stream->my_sink, 1);
|
||||
+ gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
+ ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
+ if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to play stream.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1798,9 +1822,15 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser)
|
||||
GST_ERROR("Failed to link source pads, error %d.\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
- gst_pad_set_active(stream->my_sink, 1);
|
||||
|
||||
- parser->no_more_pads = true;
|
||||
+ gst_pad_set_active(stream->my_sink, 1);
|
||||
+ gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||
+ ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||
+ if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
+ {
|
||||
+ GST_ERROR("Failed to play stream.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
2
patches/mfplat-reverts/definition
Normal file
2
patches/mfplat-reverts/definition
Normal file
@ -0,0 +1,2 @@
|
||||
# This is just a revert of update mfplat patches until it's new versions
|
||||
# of the mfplat have been merged upstream.
|
@ -1,2 +1,2 @@
|
||||
Fixes: [49692] Multiple applications need a Media Foundation media source implementation
|
||||
Disabled: True
|
||||
Depends: mfplat-reverts
|
||||
|
@ -138,6 +138,8 @@ patch_enable_all ()
|
||||
enable_krnl386_exe16_Invalid_Console_Handles="$1"
|
||||
enable_libs_Unicode_Collation="$1"
|
||||
enable_loader_KeyboardLayouts="$1"
|
||||
enable_mfplat_reverts="$1"
|
||||
enable_mfplat_streaming_support="$1"
|
||||
enable_mmsystem_dll16_MIDIHDR_Refcount="$1"
|
||||
enable_mountmgr_DosDevices="$1"
|
||||
enable_mscoree_CorValidateImage="$1"
|
||||
@ -454,6 +456,12 @@ patch_enable ()
|
||||
loader-KeyboardLayouts)
|
||||
enable_loader_KeyboardLayouts="$2"
|
||||
;;
|
||||
mfplat-reverts)
|
||||
enable_mfplat_reverts="$2"
|
||||
;;
|
||||
mfplat-streaming-support)
|
||||
enable_mfplat_streaming_support="$2"
|
||||
;;
|
||||
mmsystem.dll16-MIDIHDR_Refcount)
|
||||
enable_mmsystem_dll16_MIDIHDR_Refcount="$2"
|
||||
;;
|
||||
@ -1340,6 +1348,13 @@ if test "$enable_ntdll_WRITECOPY" -eq 1; then
|
||||
enable_ntdll_ForceBottomUpAlloc=1
|
||||
fi
|
||||
|
||||
if test "$enable_mfplat_streaming_support" -eq 1; then
|
||||
if test "$enable_mfplat_reverts" -gt 1; then
|
||||
abort "Patchset mfplat-reverts disabled, but mfplat-streaming-support depends on that."
|
||||
fi
|
||||
enable_mfplat_reverts=1
|
||||
fi
|
||||
|
||||
if test "$enable_imm32_com_initialization" -eq 1; then
|
||||
if test "$enable_winex11__NET_ACTIVE_WINDOW" -gt 1; then
|
||||
abort "Patchset winex11-_NET_ACTIVE_WINDOW disabled, but imm32-com-initialization depends on that."
|
||||
@ -2439,6 +2454,76 @@ if test "$enable_loader_KeyboardLayouts" -eq 1; then
|
||||
patch_apply loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch
|
||||
fi
|
||||
|
||||
# Patchset mfplat-reverts
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/winegstreamer/gst_private.h, dlls/winegstreamer/media_source.c, dlls/winegstreamer/quartz_parser.c,
|
||||
# | dlls/winegstreamer/wg_parser.c
|
||||
# |
|
||||
if test "$enable_mfplat_reverts" -eq 1; then
|
||||
patch_apply mfplat-reverts/0001-Revert-winegstreamer-Fix-return-code-in-init_gst-fai.patch
|
||||
patch_apply mfplat-reverts/0002-Revert-winegstreamer-Replace-source-pad-interface-wi.patch
|
||||
patch_apply mfplat-reverts/0003-Revert-winegstreamer-Allocate-source-media-buffers-i.patch
|
||||
patch_apply mfplat-reverts/0004-Revert-winegstreamer-Duplicate-source-shutdown-path-.patch
|
||||
patch_apply mfplat-reverts/0005-Revert-winegstreamer-Properly-clean-up-from-failure-.patch
|
||||
patch_apply mfplat-reverts/0006-Revert-winegstreamer-Factor-out-more-of-the-init_gst.patch
|
||||
fi
|
||||
|
||||
# Patchset mfplat-streaming-support
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * mfplat-reverts
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#49692] Multiple applications need a Media Foundation media source implementation
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/mf/topology.c, dlls/mfplat/main.c, dlls/winegstreamer/Makefile.in, dlls/winegstreamer/audioconvert.c,
|
||||
# | dlls/winegstreamer/colorconvert.c, dlls/winegstreamer/decode_transform.c, dlls/winegstreamer/gst_private.h,
|
||||
# | dlls/winegstreamer/media_source.c, dlls/winegstreamer/mfplat.c, dlls/winegstreamer/quartz_parser.c,
|
||||
# | dlls/winegstreamer/wg_parser.c, dlls/winegstreamer/winegstreamer_classes.idl, include/mfidl.idl, include/wmcodecdsp.idl
|
||||
# |
|
||||
if test "$enable_mfplat_streaming_support" -eq 1; then
|
||||
patch_apply mfplat-streaming-support/0001-winegstreamer-Activate-source-pad-in-push-mode-if-it.patch
|
||||
patch_apply mfplat-streaming-support/0002-winegstreamer-Push-stream-start-and-segment-events-i.patch
|
||||
patch_apply mfplat-streaming-support/0003-winegstreamer-Introduce-H.264-decoder-transform.patch
|
||||
patch_apply mfplat-streaming-support/0004-winegstreamer-Implement-GetInputAvailableType-for-de.patch
|
||||
patch_apply mfplat-streaming-support/0005-winegstreamer-Implement-GetOutputAvailableType-for-d.patch
|
||||
patch_apply mfplat-streaming-support/0006-winegstreamer-Implement-SetInputType-for-decode-tran.patch
|
||||
patch_apply mfplat-streaming-support/0007-winegstreamer-Implement-SetOutputType-for-decode-tra.patch
|
||||
patch_apply mfplat-streaming-support/0008-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch
|
||||
patch_apply mfplat-streaming-support/0009-winegstreamer-Add-push-mode-path-for-wg_parser.patch
|
||||
patch_apply mfplat-streaming-support/0010-winegstreamer-Implement-Process-Input-Output-for-dec.patch
|
||||
patch_apply mfplat-streaming-support/0011-winestreamer-Implement-ProcessMessage-for-decoder-tr.patch
|
||||
patch_apply mfplat-streaming-support/0012-winegstreamer-Semi-stub-GetAttributes-for-decoder-tr.patch
|
||||
patch_apply mfplat-streaming-support/0013-winegstreamer-Register-the-H.264-decoder-transform.patch
|
||||
patch_apply mfplat-streaming-support/0014-winegstreamer-Introduce-AAC-decoder-transform.patch
|
||||
patch_apply mfplat-streaming-support/0015-winegstreamer-Register-the-AAC-decoder-transform.patch
|
||||
patch_apply mfplat-streaming-support/0016-winegstreamer-Rename-GStreamer-objects-to-be-more-ge.patch
|
||||
patch_apply mfplat-streaming-support/0017-winegstreamer-Report-streams-backwards-in-media-sour.patch
|
||||
patch_apply mfplat-streaming-support/0018-winegstreamer-Implement-Process-Input-Output-for-aud.patch
|
||||
patch_apply mfplat-streaming-support/0019-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch
|
||||
patch_apply mfplat-streaming-support/0020-winegstreamer-Semi-stub-Get-Attributes-functions-for.patch
|
||||
patch_apply mfplat-streaming-support/0021-winegstreamer-Introduce-color-conversion-transform.patch
|
||||
patch_apply mfplat-streaming-support/0022-winegstreamer-Register-the-color-conversion-transfor.patch
|
||||
patch_apply mfplat-streaming-support/0023-winegstreamer-Implement-GetInputAvailableType-for-co.patch
|
||||
patch_apply mfplat-streaming-support/0024-winegstreamer-Implement-SetInputType-for-color-conve.patch
|
||||
patch_apply mfplat-streaming-support/0025-winegstreamer-Implement-GetOutputAvailableType-for-c.patch
|
||||
patch_apply mfplat-streaming-support/0026-winegstreamer-Implement-SetOutputType-for-color-conv.patch
|
||||
patch_apply mfplat-streaming-support/0027-winegstreamer-Implement-Process-Input-Output-for-col.patch
|
||||
patch_apply mfplat-streaming-support/0028-winegstreamer-Implement-ProcessMessage-for-color-con.patch
|
||||
patch_apply mfplat-streaming-support/0029-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch
|
||||
patch_apply mfplat-streaming-support/0030-mf-topology-Forward-failure-from-SetOutputType-when-.patch
|
||||
patch_apply mfplat-streaming-support/0031-winegstreamer-Handle-flush-command-in-audio-converst.patch
|
||||
patch_apply mfplat-streaming-support/0032-winegstreamer-In-the-default-configuration-select-on.patch
|
||||
patch_apply mfplat-streaming-support/0033-winegstreamer-Implement-MF_SD_LANGUAGE.patch
|
||||
patch_apply mfplat-streaming-support/0034-winegstreamer-Only-require-videobox-element-for-pars.patch
|
||||
patch_apply mfplat-streaming-support/0035-winegstreamer-Don-t-rely-on-max_size-in-unseekable-p.patch
|
||||
patch_apply mfplat-streaming-support/0036-winegstreamer-Implement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch
|
||||
patch_apply mfplat-streaming-support/0037-winegstreamer-Default-Frame-size-if-one-isn-t-availa.patch
|
||||
patch_apply mfplat-streaming-support/0038-mfplat-Stub-out-MFCreateDXGIDeviceManager-to-avoid-t.patch
|
||||
fi
|
||||
|
||||
# Patchset mmsystem.dll16-MIDIHDR_Refcount
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
Reference in New Issue
Block a user