From: Derek Lesho Subject: [PATCH v2 6/6] winegstreamer: Merge wg_parser_create and wg_parser_connect. Message-Id: <20210917195858.42475-6-dlesho@codeweavers.com> Date: Fri, 17 Sep 2021 15:58:58 -0400 In-Reply-To: <20210917195858.42475-1-dlesho@codeweavers.com> References: <20210917195858.42475-1-dlesho@codeweavers.com> Signed-off-by: Derek Lesho --- v2: Split patch three into patches 3-6. --- dlls/winegstreamer/gst_private.h | 4 +- dlls/winegstreamer/media_source.c | 5 +- dlls/winegstreamer/quartz_parser.c | 12 ++-- dlls/winegstreamer/wg_parser.c | 111 +++++++++++++++-------------- 4 files changed, 64 insertions(+), 68 deletions(-) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index a266984d969..1d0160cab2f 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -166,11 +166,9 @@ enum wg_parser_type struct unix_funcs { - struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type); + struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type, uint64_t file_size); void (CDECL *wg_parser_destroy)(struct wg_parser *parser); - HRESULT (CDECL *wg_parser_connect)(struct wg_parser *parser, uint64_t file_size); - void (CDECL *wg_parser_begin_flush)(struct wg_parser *parser); void (CDECL *wg_parser_end_flush)(struct wg_parser *parser); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index efe8f7b45cb..fa1ed002404 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1324,7 +1324,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (FAILED(hr = MFAllocateWorkQueue(&object->async_commands_queue))) goto fail; - if (!(parser = unix_funcs->wg_parser_create(WG_DECODEBIN_PARSER))) + if (!(parser = unix_funcs->wg_parser_create(WG_DECODEBIN_PARSER, file_size))) { hr = E_OUTOFMEMORY; goto fail; @@ -1335,9 +1335,6 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ object->state = SOURCE_OPENING; - if (FAILED(hr = unix_funcs->wg_parser_connect(parser, file_size))) - goto fail; - /* In Media Foundation, sources may read from any media source stream * without fear of blocking due to buffering limits on another. Trailmakers, * a Unity3D Engine game, only reads one sample from the audio stream (and diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index a89d3ec7baa..63da8b656ed 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -974,18 +974,14 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons IAsyncReader_Length(filter->reader, &file_size, &unused); - if (!(filter->wg_parser = unix_funcs->wg_parser_create(filter->parser_type))) + if (!(filter->wg_parser = unix_funcs->wg_parser_create(filter->parser_type, file_size))) { hr = E_OUTOFMEMORY; goto err; } - filter->sink_connected = true; filter->read_thread = CreateThread(NULL, 0, read_thread, filter, 0, NULL); - if (FAILED(hr = unix_funcs->wg_parser_connect(filter->wg_parser, file_size))) - goto err; - if (!filter->init_gst(filter)) { hr = E_FAIL; @@ -1000,6 +996,8 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons pin->seek.llCurrent = 0; } + filter->sink_connected = true; + return S_OK; err: GST_RemoveOutputPins(filter); @@ -1553,9 +1551,6 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) unix_funcs->wg_parser_destroy(This->wg_parser); - /* read_thread() needs to stay alive to service any read requests GStreamer - * sends, so we can only shut it down after GStreamer stops. */ - This->sink_connected = false; WaitForSingleObject(This->read_thread, INFINITE); CloseHandle(This->read_thread); @@ -1568,6 +1563,7 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) This->source_count = 0; free(This->sources); This->sources = NULL; + This->sink_connected = false; BaseFilterImpl_IncrementPinVersion(&This->filter); return S_OK; diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index a91fa3a3ed6..f6ee16c5c21 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -45,8 +45,6 @@ GST_DEBUG_CATEGORY_STATIC(wine); struct wg_parser { - BOOL (*init_gst)(struct wg_parser *parser); - struct wg_parser_stream **streams; unsigned int stream_count; @@ -1470,37 +1468,6 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use return GST_BUS_DROP; } -static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_size) -{ - if (!parser->bus) - { - parser->bus = gst_bus_new(); - gst_bus_set_sync_handler(parser->bus, bus_handler_cb, parser, NULL); - } - - 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); - - 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->error = false; - - if (!parser->init_gst(parser)) - return E_FAIL; - - gst_element_set_state(parser->container, GST_STATE_PAUSED); - - return S_OK; -} - static BOOL decodebin_parser_init_gst(struct wg_parser *parser) { GstElement *element; @@ -1622,36 +1589,80 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser) return TRUE; } -static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type) +static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type, uint64_t file_size) { struct wg_parser *parser; + BOOL ret; if (!(parser = calloc(1, sizeof(*parser)))) return NULL; + if (!(parser->appsrc = create_element("appsrc", "base"))) + { + free(parser); + return NULL; + } + + pthread_mutex_init(&parser->mutex, NULL); + pthread_cond_init(&parser->state_cond, NULL); + pthread_cond_init(&parser->read_cond, NULL); + parser->flushing = true; + + if (!parser->bus) + { + parser->bus = gst_bus_new(); + gst_bus_set_sync_handler(parser->bus, bus_handler_cb, parser, NULL); + } + + parser->container = gst_bin_new(NULL); + gst_element_set_bus(parser->container, parser->bus); + + gst_bin_add(GST_BIN(parser->container), parser->appsrc); + + 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->error = false; + switch (type) { case WG_DECODEBIN_PARSER: - parser->init_gst = decodebin_parser_init_gst; + ret = decodebin_parser_init_gst(parser); break; case WG_AVI_PARSER: - parser->init_gst = avi_parser_init_gst; + ret = avi_parser_init_gst(parser); break; case WG_MPEG_AUDIO_PARSER: - parser->init_gst = mpeg_audio_parser_init_gst; + ret = mpeg_audio_parser_init_gst(parser); break; case WG_WAVE_PARSER: - parser->init_gst = wave_parser_init_gst; + ret = wave_parser_init_gst(parser); break; default: - free(parser); - return NULL; + ret = FALSE; + break; } - pthread_mutex_init(&parser->mutex, NULL); - pthread_cond_init(&parser->state_cond, NULL); - pthread_cond_init(&parser->read_cond, NULL); - parser->flushing = true; + if (!ret) + { + gst_element_set_bus(parser->container, NULL); + gst_object_unref(parser->container); + + gst_bus_set_sync_handler(parser->bus, NULL, NULL, NULL); + gst_object_unref(parser->bus); + + pthread_mutex_destroy(&parser->mutex); + pthread_cond_destroy(&parser->state_cond); + pthread_cond_destroy(&parser->read_cond); + + free(parser); + return NULL; + } + + gst_element_set_state(parser->container, GST_STATE_PAUSED); GST_DEBUG("Created winegstreamer parser %p.\n", parser); return parser; @@ -1679,19 +1690,15 @@ static void CDECL wg_parser_destroy(struct wg_parser *parser) } pthread_mutex_unlock(&parser->mutex); - if (parser->container) - gst_element_set_state(parser->container, GST_STATE_NULL); + gst_element_set_state(parser->container, GST_STATE_NULL); for (i = 0; i < parser->stream_count; ++i) free_stream(parser->streams[i]); free(parser->streams); - if (parser->container) - { - gst_element_set_bus(parser->container, NULL); - gst_object_unref(parser->container); - } + gst_element_set_bus(parser->container, NULL); + gst_object_unref(parser->container); gst_bus_set_sync_handler(parser->bus, NULL, NULL, NULL); gst_object_unref(parser->bus); @@ -1708,8 +1715,6 @@ static const struct unix_funcs funcs = wg_parser_create, wg_parser_destroy, - wg_parser_connect, - wg_parser_begin_flush, wg_parser_end_flush, -- 2.33.0