Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/quartz_parser.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index bb7a71283c3..f38a0c16215 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -1629,6 +1629,15 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) if (!This->sink_connected) return S_OK;
+ /* Disconnecting source pins triggers a call to wg_parser_stream_disable(). + * The stream pointers are no longer valid after wg_parser_disconnect(), so + * make sure we disable the streams first. */ + for (i = 0; i < This->source_count; ++i) + { + if (This->sources[i]) + free_source_pin(This->sources[i]); + } + wg_parser_disconnect(This->wg_parser);
/* read_thread() needs to stay alive to service any read requests GStreamer @@ -1637,12 +1646,6 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) WaitForSingleObject(This->read_thread, INFINITE); CloseHandle(This->read_thread);
- for (i = 0; i < This->source_count; ++i) - { - if (This->sources[i]) - free_source_pin(This->sources[i]); - } - This->source_count = 0; free(This->sources); This->sources = NULL;
It is accessed from multiple threads.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wg_parser.c | 38 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index df563e9336e..a2ce92ccdc7 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -205,10 +205,15 @@ static NTSTATUS wg_parser_stream_enable(void *args) const struct wg_parser_stream_enable_params *params = args; struct wg_parser_stream *stream = params->stream; const struct wg_format *format = params->format; + struct wg_parser *parser = stream->parser; + + pthread_mutex_lock(&parser->mutex);
stream->current_format = *format; stream->enabled = true;
+ pthread_mutex_unlock(&parser->mutex); + if (format->major_type == WG_MAJOR_TYPE_VIDEO) { bool flip = (format->u.video.height < 0); @@ -245,8 +250,11 @@ static NTSTATUS wg_parser_stream_enable(void *args) static NTSTATUS wg_parser_stream_disable(void *args) { struct wg_parser_stream *stream = args; + struct wg_parser *parser = stream->parser;
+ pthread_mutex_lock(&parser->mutex); stream->enabled = false; + pthread_mutex_unlock(&parser->mutex); return S_OK; }
@@ -437,6 +445,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) switch (event->type) { case GST_EVENT_SEGMENT: + pthread_mutex_lock(&parser->mutex); if (stream->enabled) { const GstSegment *segment; @@ -445,29 +454,31 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
if (segment->format != GST_FORMAT_TIME) { + pthread_mutex_unlock(&parser->mutex); GST_FIXME("Unhandled format "%s".", gst_format_get_name(segment->format)); break; }
gst_segment_copy_into(segment, &stream->segment); } + pthread_mutex_unlock(&parser->mutex); break;
case GST_EVENT_EOS: pthread_mutex_lock(&parser->mutex); stream->eos = true; - pthread_mutex_unlock(&parser->mutex); if (stream->enabled) pthread_cond_signal(&stream->event_cond); else pthread_cond_signal(&parser->init_cond); + pthread_mutex_unlock(&parser->mutex); break;
case GST_EVENT_FLUSH_START: + pthread_mutex_lock(&parser->mutex); + if (stream->enabled) { - pthread_mutex_lock(&parser->mutex); - stream->flushing = true; pthread_cond_signal(&stream->event_empty_cond);
@@ -477,9 +488,9 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) gst_buffer_unref(stream->buffer); stream->buffer = NULL; } - - pthread_mutex_unlock(&parser->mutex); } + + pthread_mutex_unlock(&parser->mutex); break;
case GST_EVENT_FLUSH_STOP: @@ -528,8 +539,11 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu
GST_LOG("stream %p, buffer %p.", stream, buffer);
+ pthread_mutex_lock(&parser->mutex); + if (!stream->enabled) { + pthread_mutex_unlock(&parser->mutex); gst_buffer_unref(buffer); return GST_FLOW_OK; } @@ -537,8 +551,6 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu /* Allow this buffer to be flushed by GStreamer. We are effectively * implementing a queue object here. */
- pthread_mutex_lock(&parser->mutex); - while (!stream->flushing && stream->buffer) pthread_cond_wait(&stream->event_empty_cond, &parser->mutex); if (stream->flushing) @@ -573,6 +585,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) { struct wg_parser_stream *stream = gst_pad_get_element_private(pad); + struct wg_parser *parser = stream->parser;
GST_LOG("stream %p, type "%s".", stream, gst_query_type_get_name(query->type));
@@ -585,10 +598,15 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)
gst_query_parse_caps(query, &filter);
+ pthread_mutex_lock(&parser->mutex); + if (stream->enabled) caps = wg_format_to_caps(&stream->current_format); else caps = gst_caps_new_any(); + + pthread_mutex_unlock(&parser->mutex); + if (!caps) return FALSE;
@@ -614,8 +632,11 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) gboolean ret = TRUE; GstCaps *caps;
+ pthread_mutex_lock(&parser->mutex); + if (!stream->enabled) { + pthread_mutex_unlock(&parser->mutex); gst_query_set_accept_caps_result(query, TRUE); return TRUE; } @@ -623,6 +644,9 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) gst_query_parse_accept_caps(query, &caps); wg_format_from_caps(&format, caps); ret = wg_format_compare(&format, &stream->current_format); + + pthread_mutex_unlock(&parser->mutex); + if (!ret && gst_debug_category_get_threshold(GST_CAT_DEFAULT) >= GST_LEVEL_WARNING) { gchar *str = gst_caps_to_string(caps);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wg_parser.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index a2ce92ccdc7..e7a60ec158a 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -255,6 +255,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) pthread_mutex_lock(&parser->mutex); stream->enabled = false; pthread_mutex_unlock(&parser->mutex); + pthread_cond_signal(&stream->event_empty_cond); return S_OK; }
@@ -541,6 +542,12 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu
pthread_mutex_lock(&parser->mutex);
+ /* Allow this buffer to be flushed by GStreamer. We are effectively + * implementing a queue object here. */ + + while (stream->enabled && !stream->flushing && stream->buffer) + pthread_cond_wait(&stream->event_empty_cond, &parser->mutex); + if (!stream->enabled) { pthread_mutex_unlock(&parser->mutex); @@ -548,11 +555,6 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu return GST_FLOW_OK; }
- /* Allow this buffer to be flushed by GStreamer. We are effectively - * implementing a queue object here. */ - - while (!stream->flushing && stream->buffer) - pthread_cond_wait(&stream->event_empty_cond, &parser->mutex); if (stream->flushing) { pthread_mutex_unlock(&parser->mutex);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/main.c | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 8a41df6b223..d88a462d81e 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -70,13 +70,20 @@ struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buff .unlimited_buffering = unlimited_buffering, };
+ TRACE("type %#x, unlimited_buffering %d.\n", type, unlimited_buffering); + if (__wine_unix_call(unix_handle, unix_wg_parser_create, ¶ms)) return NULL; + + TRACE("Returning parser %p.\n", params.parser); + return params.parser; }
void wg_parser_destroy(struct wg_parser *parser) { + TRACE("parser %p.\n", parser); + __wine_unix_call(unix_handle, unix_wg_parser_destroy, parser); }
@@ -88,11 +95,15 @@ HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size) .file_size = file_size, };
+ TRACE("parser %p, file_size %I64u.\n", parser, file_size); + return __wine_unix_call(unix_handle, unix_wg_parser_connect, ¶ms); }
void wg_parser_disconnect(struct wg_parser *parser) { + TRACE("parser %p.\n", parser); + __wine_unix_call(unix_handle, unix_wg_parser_disconnect, parser); }
@@ -103,6 +114,8 @@ bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, .parser = parser, };
+ TRACE("parser %p, offset %p, size %p.\n", parser, offset, size); + if (__wine_unix_call(unix_handle, unix_wg_parser_get_next_read_offset, ¶ms)) return false; *offset = params.offset; @@ -119,6 +132,8 @@ void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t si .size = size, };
+ TRACE("parser %p, data %p, size %u.\n", parser, data, size); + __wine_unix_call(unix_handle, unix_wg_parser_push_data, ¶ms); }
@@ -129,6 +144,8 @@ uint32_t wg_parser_get_stream_count(struct wg_parser *parser) .parser = parser, };
+ TRACE("parser %p.\n", parser); + __wine_unix_call(unix_handle, unix_wg_parser_get_stream_count, ¶ms); return params.count; } @@ -141,7 +158,11 @@ struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t .index = index, };
+ TRACE("parser %p, index %u.\n", parser, index); + __wine_unix_call(unix_handle, unix_wg_parser_get_stream, ¶ms); + + TRACE("Returning stream %p.\n", params.stream); return params.stream; }
@@ -153,6 +174,8 @@ void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, stru .format = format, };
+ TRACE("stream %p, format %p.\n", stream, format); + __wine_unix_call(unix_handle, unix_wg_parser_stream_get_preferred_format, ¶ms); }
@@ -164,11 +187,15 @@ void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_fo .format = format, };
+ TRACE("stream %p, format %p.\n", stream, format); + __wine_unix_call(unix_handle, unix_wg_parser_stream_enable, ¶ms); }
void wg_parser_stream_disable(struct wg_parser_stream *stream) { + TRACE("stream %p.\n", stream); + __wine_unix_call(unix_handle, unix_wg_parser_stream_disable, stream); }
@@ -180,6 +207,8 @@ bool wg_parser_stream_get_buffer(struct wg_parser_stream *stream, struct wg_pars .buffer = buffer, };
+ TRACE("stream %p, buffer %p.\n", stream, buffer); + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_buffer, ¶ms); }
@@ -194,11 +223,15 @@ bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, .size = size, };
+ TRACE("stream %p, data %p, offset %u, size %u.\n", stream, data, offset, size); + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_copy_buffer, ¶ms); }
void wg_parser_stream_release_buffer(struct wg_parser_stream *stream) { + TRACE("stream %p.\n", stream); + __wine_unix_call(unix_handle, unix_wg_parser_stream_release_buffer, stream); }
@@ -214,6 +247,9 @@ void wg_parser_stream_notify_qos(struct wg_parser_stream *stream, .timestamp = timestamp, };
+ TRACE("stream %p, underflow %d, proportion %.16e, diff %I64d, timestamp %I64u.\n", + stream, underflow, proportion, diff, timestamp); + __wine_unix_call(unix_handle, unix_wg_parser_stream_notify_qos, ¶ms); }
@@ -224,7 +260,11 @@ uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream) .stream = stream, };
+ TRACE("stream %p.\n", stream); + __wine_unix_call(unix_handle, unix_wg_parser_stream_get_duration, ¶ms); + + TRACE("Returning duration %I64u.\n", params.duration); return params.duration; }
@@ -241,6 +281,9 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, .stop_flags = stop_flags, };
+ TRACE("stream %p, rate %.16e, start_pos %I64u, stop_pos %I64u, start_flags %#lx, stop_flags %#lx.\n", + stream, rate, start_pos, stop_pos, start_flags, stop_flags); + __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, ¶ms); }
@@ -253,13 +296,19 @@ struct wg_transform *wg_transform_create(const struct wg_format *input_format, .output_format = output_format, };
+ TRACE("input_format %p, output_format %p.\n", input_format, output_format); + if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms)) return NULL; + + TRACE("Returning transform %p.\n", params.transform); return params.transform; }
void wg_transform_destroy(struct wg_transform *transform) { + TRACE("transform %p.\n", transform); + __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); }
@@ -272,6 +321,8 @@ HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample }; NTSTATUS status;
+ TRACE("transform %p, sample %p.\n", transform, sample); + if ((status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms))) return HRESULT_FROM_NT(status);
@@ -287,6 +338,8 @@ HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample }; NTSTATUS status;
+ TRACE("transform %p, sample %p.\n", transform, sample); + if ((status = __wine_unix_call(unix_handle, unix_wg_transform_read_data, ¶ms))) return HRESULT_FROM_NT(status);