From: Conor McCarthy <cmccarthy@codeweavers.com> If a dynamic format change occurs in a stream, the resulting flush may cause another stream to first set stream->buffer to null, and then replace it with a new buffer which does not match the info subsequently used by wg_parser_stream_copy_buffer(). If the new buffer is smaller, the result is an assertion failure. This issue has been observed in SHOGUN: Total War Collection and Ys I & II Chronicles. --- dlls/winegstreamer/wg_parser.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 1a29015356e..9090ce25afe 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -115,7 +115,7 @@ struct wg_parser_stream GstBuffer *buffer; GstMapInfo map_info; - bool flushing, eos, enabled, has_tags, has_buffer, no_more_pads; + bool flushing, eos, enabled, has_tags, has_buffer, no_more_pads, get_buffer_called; uint64_t duration; gchar *tags[WG_PARSER_TAG_COUNT]; @@ -377,6 +377,8 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) wg_buffer->size = gst_buffer_get_size(buffer); wg_buffer->stream = stream->number; + stream->get_buffer_called = true; + pthread_mutex_unlock(&parser->mutex); return S_OK; } @@ -391,7 +393,7 @@ static NTSTATUS wg_parser_stream_copy_buffer(void *args) pthread_mutex_lock(&parser->mutex); - if (!stream->buffer) + if (!stream->buffer || !stream->get_buffer_called) { pthread_mutex_unlock(&parser->mutex); return VFW_E_WRONG_STATE; @@ -419,6 +421,8 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) stream->buffer = NULL; } + stream->get_buffer_called = false; + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&stream->event_empty_cond); @@ -661,6 +665,8 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) stream->buffer = NULL; } + stream->get_buffer_called = false; + pthread_mutex_unlock(&parser->mutex); break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10256