From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 35 ++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index c6403661c0f..58ea8ed0c2b 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -27,6 +27,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+#define SOURCE_BUFFER_SIZE (64 * 1024) + struct object_context { IUnknown IUnknown_iface; @@ -37,6 +39,7 @@ struct object_context UINT64 file_size; WCHAR *url;
+ BYTE *buffer; wg_source_t wg_source; };
@@ -84,6 +87,7 @@ static ULONG WINAPI object_context_Release(IUnknown *iface) wg_source_destroy(context->wg_source); IMFAsyncResult_Release(context->result); IMFByteStream_Release(context->stream); + free(context->buffer); free(context->url); free(context); } @@ -99,14 +103,16 @@ static const IUnknownVtbl object_context_vtbl = };
static HRESULT object_context_create(DWORD flags, IMFByteStream *stream, const WCHAR *url, - QWORD file_size, IMFAsyncResult *result, IUnknown **out) + QWORD file_size, IMFAsyncResult *result, IUnknown **out, BYTE **out_buf) { WCHAR *tmp_url = url ? wcsdup(url) : NULL; struct object_context *context;
- if (!(context = calloc(1, sizeof(*context)))) + if (!(context = calloc(1, sizeof(*context))) + || !(context->buffer = malloc(SOURCE_BUFFER_SIZE))) { free(tmp_url); + free(context); return E_OUTOFMEMORY; }
@@ -120,6 +126,7 @@ static HRESULT object_context_create(DWORD flags, IMFByteStream *stream, const W IMFAsyncResult_AddRef(context->result);
*out = &context->IUnknown_iface; + *out_buf = context->buffer; return S_OK; }
@@ -1861,7 +1868,8 @@ static HRESULT WINAPI stream_handler_BeginCreateObject(IMFByteStreamHandler *ifa struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); IMFAsyncResult *result; IUnknown *context; - QWORD file_size; + QWORD file_size, position; + BYTE *buffer; HRESULT hr; DWORD caps;
@@ -1890,13 +1898,16 @@ static HRESULT WINAPI stream_handler_BeginCreateObject(IMFByteStreamHandler *ifa
if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result))) return hr; - if (FAILED(hr = object_context_create(flags, stream, url, file_size, result, &context))) - { - IMFAsyncResult_Release(result); - return hr; - } + if (FAILED(hr = object_context_create(flags, stream, url, file_size, result, &context, &buffer))) + goto done;
- hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_IO, &handler->IMFAsyncCallback_iface, context); + if (FAILED(hr = IMFByteStream_GetCurrentPosition(stream, &position))) + WARN("Failed to get byte stream position, hr %#lx\n", hr); + else if (position != 0 && FAILED(hr = IMFByteStream_SetCurrentPosition(stream, 0))) + WARN("Failed to set byte stream position, hr %#lx\n", hr); + else if (FAILED(hr = IMFByteStream_BeginRead(stream, buffer, min(SOURCE_BUFFER_SIZE, file_size), + &handler->IMFAsyncCallback_iface, context))) + WARN("Failed to queue byte stream async read, hr %#lx\n", hr); IUnknown_Release(context);
if (SUCCEEDED(hr) && cancel_cookie) @@ -1905,6 +1916,7 @@ static HRESULT WINAPI stream_handler_BeginCreateObject(IMFByteStreamHandler *ifa IUnknown_AddRef(*cancel_cookie); }
+done: IMFAsyncResult_Release(result);
return hr; @@ -2004,12 +2016,15 @@ static HRESULT WINAPI stream_handler_callback_Invoke(IMFAsyncCallback *iface, IM IUnknown *object, *state = IMFAsyncResult_GetStateNoAddRef(result); struct object_context *context; struct result_entry *entry; + DWORD size = 0; HRESULT hr;
if (!state || !(context = impl_from_IUnknown(state))) return E_INVALIDARG;
- if (FAILED(hr = wg_source_create(&context->wg_source))) + 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))) 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);