From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 3 ++- dlls/winegstreamer/main.c | 7 +++--- dlls/winegstreamer/media_source.c | 25 +++++++++------------- dlls/winegstreamer/quartz_parser.c | 26 +++++++++-------------- dlls/winegstreamer/unixlib.h | 3 +-- dlls/winegstreamer/wg_parser.c | 14 ++++++------ dlls/winegstreamer/wg_sample.c | 34 ++++++++++++++++++++++++++++++ dlls/winegstreamer/wm_reader.c | 27 ++++++++++-------------- 8 files changed, 78 insertions(+), 61 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 2552e1d7f61..9974090ecf2 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -77,7 +77,7 @@ HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size); void wg_parser_disconnect(struct wg_parser *parser);
bool wg_parser_wait_request(struct wg_parser *parser, struct wg_request *request); -void wg_parser_reply_read(struct wg_parser *parser, const void *data, uint32_t size); +void wg_parser_reply_read(struct wg_parser *parser, struct wg_sample *sample);
uint32_t wg_parser_get_stream_count(struct wg_parser *parser); struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index); @@ -123,6 +123,7 @@ extern HRESULT mfplat_DllRegisterServer(void); IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format); void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
+HRESULT wg_sample_create_raw(UINT32 size, struct wg_sample **out); HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out); HRESULT wg_sample_create_quartz(IMediaSample *sample, struct wg_sample **out); void wg_sample_release(struct wg_sample *wg_sample); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 25f0c38b700..0beae8f4b31 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -122,16 +122,15 @@ bool wg_parser_wait_request(struct wg_parser *parser, struct wg_request *wg_requ return true; }
-void wg_parser_reply_read(struct wg_parser *parser, const void *data, uint32_t size) +void wg_parser_reply_read(struct wg_parser *parser, struct wg_sample *sample) { struct wg_parser_reply_read_params params = { .parser = parser, - .data = data, - .size = size, + .sample = sample, };
- TRACE("parser %p, data %p, size %u.\n", parser, data, size); + TRACE("parser %p, sample %p.\n", parser, sample);
__wine_unix_call(unix_handle, unix_wg_parser_reply_read, ¶ms); } diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 5b98c90a8b4..401ad22c06b 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -593,26 +593,25 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = };
static void handle_read_request(struct media_source *source, QWORD file_size, - void **buffer, size_t *buffer_size, struct wg_request *request) + struct wg_request *request) { IMFByteStream *byte_stream = source->byte_stream; uint64_t offset = request->u.read.offset; uint32_t size = request->u.read.size; + struct wg_sample *wg_sample; ULONG ret_size = 0; HRESULT hr; - void *data;
if (offset >= file_size) size = 0; else if (offset + size >= file_size) size = file_size - offset;
- if (!array_reserve(buffer, buffer_size, size, 1)) + if (FAILED(wg_sample_create_raw(size, &wg_sample))) { - wg_parser_reply_read(source->wg_parser, NULL, 0); + wg_parser_reply_read(source->wg_parser, NULL); return; } - data = *buffer;
/* Some IMFByteStreams (including the standard file-based stream) return * an error when reading past the file size. */ @@ -620,12 +619,12 @@ static void handle_read_request(struct media_source *source, QWORD file_size, if (!size) hr = S_OK; else if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset))) - hr = IMFByteStream_Read(byte_stream, data, size, &ret_size); + hr = IMFByteStream_Read(byte_stream, wg_sample->data, size, &ret_size);
if (FAILED(hr)) { ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - data = NULL; + wg_sample->data = NULL; } else if (ret_size != size) { @@ -633,19 +632,16 @@ static void handle_read_request(struct media_source *source, QWORD file_size, size = ret_size; }
- wg_parser_reply_read(source->wg_parser, data, size); + wg_sample->size = size; + wg_parser_reply_read(source->wg_parser, wg_sample); + wg_sample_release(wg_sample); }
static DWORD CALLBACK read_thread(void *arg) { struct media_source *source = arg; IMFByteStream *byte_stream = source->byte_stream; - size_t buffer_size = 4096; QWORD file_size; - void *data; - - if (!(data = malloc(buffer_size))) - return 0;
IMFByteStream_GetLength(byte_stream, &file_size);
@@ -661,7 +657,7 @@ static DWORD CALLBACK read_thread(void *arg) switch (request.type) { case WG_REQUEST_READ: - handle_read_request(source, file_size, &data, &buffer_size, &request); + handle_read_request(source, file_size, &request); break;
default: @@ -670,7 +666,6 @@ static DWORD CALLBACK read_thread(void *arg) } }
- free(data); TRACE("Media source is shutting down; exiting.\n"); return 0; } diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index edf7ed6454b..dc2be99d5e3 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -866,45 +866,40 @@ static DWORD CALLBACK stream_thread(void *arg) }
static void handle_read_request(struct parser *filter, LONGLONG file_size, - void **buffer, size_t *buffer_size, struct wg_request *request) + struct wg_request *request) { uint64_t offset = request->u.read.offset; uint32_t size = request->u.read.size; + struct wg_sample *wg_sample; HRESULT hr; - void *data;
if (offset >= file_size) size = 0; else if (offset + size >= file_size) size = file_size - offset;
- if (!array_reserve(buffer, buffer_size, size, 1)) + if (FAILED(wg_sample_create_raw(size, &wg_sample))) { - wg_parser_reply_read(filter->wg_parser, NULL, 0); + wg_parser_reply_read(filter->wg_parser, NULL); return; } - data = *buffer; - - hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);
+ hr = IAsyncReader_SyncRead(filter->reader, offset, size, wg_sample->data); if (FAILED(hr)) { ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - data = NULL; + wg_sample->data = NULL; }
- wg_parser_reply_read(filter->wg_parser, data, size); + wg_sample->size = size; + wg_parser_reply_read(filter->wg_parser, wg_sample); + wg_sample_release(wg_sample); }
static DWORD CALLBACK read_thread(void *arg) { struct parser *filter = arg; LONGLONG file_size, unused; - size_t buffer_size = 4096; - void *data; - - if (!(data = malloc(buffer_size))) - return 0;
IAsyncReader_Length(filter->reader, &file_size, &unused);
@@ -920,7 +915,7 @@ static DWORD CALLBACK read_thread(void *arg) switch (request.type) { case WG_REQUEST_READ: - handle_read_request(filter, file_size, &data, &buffer_size, &request); + handle_read_request(filter, file_size, &request); break;
default: @@ -929,7 +924,6 @@ static DWORD CALLBACK read_thread(void *arg) } }
- free(data); TRACE("Streaming stopped; exiting.\n"); return 0; } diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index f767daed513..a621ea9d4bf 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -192,8 +192,7 @@ struct wg_parser_wait_request_params struct wg_parser_reply_read_params { struct wg_parser *parser; - const void *data; - UINT32 size; + struct wg_sample *sample; };
struct wg_parser_get_stream_count_params diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 56525da1348..ee3ed1807d2 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -154,21 +154,20 @@ static NTSTATUS wg_parser_reply_read(void *args) { const struct wg_parser_reply_read_params *params = args; struct wg_parser *parser = params->parser; - const void *data = params->data; - uint32_t size = params->size; + struct wg_sample *sample = params->sample; GstBuffer *buffer = NULL; GstFlowReturn result;
- if (!data) + if (!sample || !sample->data) result = GST_FLOW_ERROR; - else if (!size) + else if (!sample->size) result = GST_FLOW_EOS; - else if (!(buffer = gst_buffer_new_and_alloc(size))) + else if (!(buffer = gst_buffer_new_and_alloc(sample->size))) result = GST_FLOW_ERROR; else { - gst_buffer_fill(buffer, 0, data, size); - GST_INFO("Copied %u bytes from data %p to buffer %p", size, data, buffer); + gst_buffer_fill(buffer, 0, sample->data, sample->size); + GST_INFO("Copied %u bytes from sample %p to buffer %p", sample->size, sample, buffer); result = GST_FLOW_OK; }
@@ -901,6 +900,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
*buffer = parser->read_request.buffer; + parser->read_request.buffer = NULL; ret = parser->read_request.ret;
pthread_mutex_unlock(&parser->mutex); diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index ae8a2d4d0c7..eb46982fabf 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -47,6 +47,11 @@ struct sample
union { + struct + { + void *__pad[3]; + BYTE buffer[]; + } raw; struct { IMFSample *sample; @@ -59,6 +64,35 @@ struct sample } u; };
+C_ASSERT(sizeof(struct sample) == offsetof(struct sample, u.raw.buffer[0])); + +static void raw_sample_destroy(struct wg_sample *wg_sample) +{ + TRACE("wg_sample %p\n", wg_sample); +} + +static const struct wg_sample_ops raw_sample_ops = +{ + raw_sample_destroy, +}; + +HRESULT wg_sample_create_raw(UINT32 size, struct wg_sample **out) +{ + struct sample *sample; + + if (!(sample = calloc(1, offsetof(struct sample, u.raw.buffer[size])))) + return E_OUTOFMEMORY; + + sample->wg_sample.data = sample->u.raw.buffer; + sample->wg_sample.size = 0; + sample->wg_sample.max_size = size; + sample->ops = &raw_sample_ops; + + TRACE("Created wg_sample %p, size %u.\n", &sample->wg_sample, size); + *out = &sample->wg_sample; + return S_OK; +} + static const struct wg_sample_ops mf_sample_ops;
static inline struct sample *unsafe_mf_from_wg_sample(struct wg_sample *wg_sample) diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 9de7ab6edf3..a2851f8df31 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -527,28 +527,27 @@ static const IWMMediaPropsVtbl stream_props_vtbl = };
static void handle_read_request(struct wm_reader *reader, uint64_t file_size, - void **buffer, size_t *buffer_size, struct wg_request *request) + struct wg_request *request) { uint64_t offset = request->u.read.offset; IStream *stream = reader->source_stream; uint32_t size = request->u.read.size; + struct wg_sample *wg_sample; LARGE_INTEGER large_offset; HANDLE file = reader->file; ULONG ret_size = 0; HRESULT hr; - void *data;
if (offset >= file_size) size = 0; else if (offset + size >= file_size) size = file_size - offset;
- if (!array_reserve(buffer, buffer_size, size, 1)) + if (FAILED(wg_sample_create_raw(size, &wg_sample))) { - wg_parser_reply_read(reader->wg_parser, NULL, 0); + wg_parser_reply_read(reader->wg_parser, NULL); return; } - data = *buffer;
large_offset.QuadPart = offset; if (!size) @@ -556,7 +555,7 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size, else if (file) { if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN) - || !ReadFile(file, data, size, &ret_size, NULL)) + || !ReadFile(file, wg_sample->data, size, &ret_size, NULL)) hr = HRESULT_FROM_WIN32(GetLastError()); else hr = S_OK; @@ -564,13 +563,13 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size, else { if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL))) - hr = IStream_Read(stream, data, size, &ret_size); + hr = IStream_Read(stream, wg_sample->data, size, &ret_size); }
if (FAILED(hr)) { ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - data = NULL; + wg_sample->data = NULL; } else if (ret_size != size) { @@ -578,7 +577,9 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size, size = ret_size; }
- wg_parser_reply_read(reader->wg_parser, data, size); + wg_sample->size = size; + wg_parser_reply_read(reader->wg_parser, wg_sample); + wg_sample_release(wg_sample); }
static DWORD CALLBACK read_thread(void *arg) @@ -586,12 +587,7 @@ static DWORD CALLBACK read_thread(void *arg) struct wm_reader *reader = arg; IStream *stream = reader->source_stream; HANDLE file = reader->file; - size_t buffer_size = 4096; uint64_t file_size; - void *data; - - if (!(data = malloc(buffer_size))) - return 0;
if (file) { @@ -620,7 +616,7 @@ static DWORD CALLBACK read_thread(void *arg) switch (request.type) { case WG_REQUEST_READ: - handle_read_request(reader, file_size, &data, &buffer_size, &request); + handle_read_request(reader, file_size, &request); break;
default: @@ -629,7 +625,6 @@ static DWORD CALLBACK read_thread(void *arg) } }
- free(data); TRACE("Reader is shutting down; exiting.\n"); return 0; }