From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/gst_private.h | 2 +- dlls/winegstreamer/main.c | 17 +++++++++++++--- dlls/winegstreamer/media_source.c | 2 +- dlls/winegstreamer/unixlib.h | 3 +++ dlls/winegstreamer/wg_parser.c | 24 +++++++++++++++++++++- dlls/winegstreamer/wg_source.c | 33 +++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 6380b8fb7ff..11dfbf8e0b5 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -104,7 +104,7 @@ char *wg_parser_stream_get_tag(wg_parser_stream_t stream, enum wg_parser_tag tag void wg_parser_stream_seek(wg_parser_stream_t stream, double rate, uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags);
-HRESULT wg_source_create(wg_source_t *out); +HRESULT wg_source_create(const WCHAR *url, const void *data, uint32_t size, wg_source_t *out); void wg_source_destroy(wg_source_t source);
HRESULT wg_transform_create_mf(IMFMediaType *input_type, IMFMediaType *output_type, diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 92a44be0c96..04bff47bd5c 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -435,12 +435,22 @@ void wg_parser_stream_seek(wg_parser_stream_t stream, double rate, WINE_UNIX_CALL(unix_wg_parser_stream_seek, ¶ms); }
-HRESULT wg_source_create(wg_source_t *out) +HRESULT wg_source_create(const WCHAR *url, const void *data, uint32_t size, wg_source_t *out) { - struct wg_source_create_params params = {0}; + struct wg_source_create_params params = + { + .data = data, .size = size, + }; + char *tmp = NULL; NTSTATUS status; + UINT len; + + TRACE("url %s, data %p, size %#x\n", debugstr_w(url), data, size);
- TRACE("out %p\n", out); + if (url && (len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL))) + tmp = malloc(len); + if ((params.url = tmp)) + WideCharToMultiByte(CP_ACP, 0, url, -1, tmp, len, NULL, NULL);
if ((status = WINE_UNIX_CALL(unix_wg_source_create, ¶ms))) WARN("wg_source_create returned status %#lx\n", status); @@ -450,6 +460,7 @@ HRESULT wg_source_create(wg_source_t *out) *out = params.source; }
+ free(tmp); return HRESULT_FROM_NT(status); }
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 61a93ffa4ba..ffc7d652934 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -2028,7 +2028,7 @@ static HRESULT WINAPI stream_handler_callback_Invoke(IMFAsyncCallback *iface, IM
if (FAILED(hr = IMFByteStream_EndRead(context->stream, result, &size))) WARN("Failed to complete stream read, hr %#lx\n", hr); - else if (FAILED(hr = wg_source_create(&context->wg_source))) + else if (FAILED(hr = wg_source_create(context->url, context->buffer, size, &context->wg_source))) WARN("Failed to create wg_source, hr %#lx\n", hr); else if (FAILED(hr = media_source_create(context, (IMFMediaSource **)&object))) WARN("Failed to create media source, hr %#lx\n", hr); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 0a98aadd1ab..9eab68e14da 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -332,6 +332,9 @@ struct wg_parser_stream_seek_params
struct wg_source_create_params { + const char *url; + const void *data; + UINT32 size; wg_source_t source; };
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 51753b1f429..60dca79ef16 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -2063,6 +2063,28 @@ static NTSTATUS wow64_wg_parser_stream_get_tag(void *args) return wg_parser_stream_get_tag(¶ms); }
+NTSTATUS wow64_wg_source_create(void *args) +{ + struct + { + PTR32 url; + PTR32 data; + UINT32 size; + wg_source_t source; + } *params32 = args; + struct wg_source_create_params params = + { + .url = ULongToPtr(params32->url), + .data = ULongToPtr(params32->data), + .size = params32->size, + }; + NTSTATUS ret; + + ret = wg_source_create(¶ms); + params32->source = params.source; + return ret; +} + NTSTATUS wow64_wg_transform_create(void *args) { struct @@ -2287,7 +2309,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X64(wg_parser_stream_get_tag), X(wg_parser_stream_seek),
- X(wg_source_create), + X64(wg_source_create), X(wg_source_destroy),
X64(wg_transform_create), diff --git a/dlls/winegstreamer/wg_source.c b/dlls/winegstreamer/wg_source.c index 52a54196ea9..071b800b6d1 100644 --- a/dlls/winegstreamer/wg_source.c +++ b/dlls/winegstreamer/wg_source.c @@ -49,13 +49,42 @@ static struct wg_source *get_source(wg_source_t source) return (struct wg_source *)(ULONG_PTR)source; }
+static GstCaps *detect_caps_from_data(const char *url, const void *data, guint size) +{ + const char *extension = url ? strrchr(url, '.') : NULL; + GstTypeFindProbability probability; + GstCaps *caps; + + GST_LOG("url %s, data %p, size %#x", url, data, size); + + if (!(caps = gst_type_find_helper_for_data_with_extension(NULL, data, size, + extension ? extension + 1 : NULL, &probability))) + { + GST_ERROR("Failed to detect caps for url %s", url); + return NULL; + } + + if (probability > GST_TYPE_FIND_POSSIBLE) + GST_INFO("Got probability %u for caps %" GST_PTR_FORMAT, probability, caps); + else + GST_FIXME("Got probability %u for caps %" GST_PTR_FORMAT, probability, caps); + + return caps; +} + NTSTATUS wg_source_create(void *args) { struct wg_source_create_params *params = args; struct wg_source *source; + GstCaps *src_caps;
+ if (!(src_caps = detect_caps_from_data(params->url, params->data, params->size))) + return STATUS_UNSUCCESSFUL; if (!(source = calloc(1, sizeof(*source)))) + { + gst_caps_unref(src_caps); return STATUS_UNSUCCESSFUL; + }
if (!(source->container = gst_bin_new("wg_source"))) goto error; @@ -64,6 +93,8 @@ NTSTATUS wg_source_create(void *args) if (!gst_element_get_state(source->container, NULL, NULL, -1)) goto error;
+ gst_caps_unref(src_caps); + params->source = (wg_source_t)(ULONG_PTR)source; GST_INFO("Created winegstreamer source %p.", source); return STATUS_SUCCESS; @@ -76,6 +107,8 @@ error: } free(source);
+ gst_caps_unref(src_caps); + GST_ERROR("Failed to create winegstreamer source."); return STATUS_UNSUCCESSFUL; }