[PATCH 5/5] winegstreamer: Use wg_sample to provide data in wg_parser_reply_read.
Rémi Bernon
wine at gitlab.winehq.org
Tue Jun 14 02:27:03 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at 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;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/242
More information about the wine-devel
mailing list