[PATCH 3/6] winegstreamer: Read media_source stream data using wg_sample struct.

Rémi Bernon wine at gitlab.winehq.org
Fri Jun 3 04:17:12 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  |  1 +
 dlls/winegstreamer/main.c         | 13 +++++
 dlls/winegstreamer/media_source.c | 81 +++++++++++--------------------
 dlls/winegstreamer/unix_private.h |  3 ++
 dlls/winegstreamer/unixlib.h      |  7 +++
 dlls/winegstreamer/wg_parser.c    | 30 ++++++++++++
 dlls/winegstreamer/wg_transform.c |  4 +-
 7 files changed, 84 insertions(+), 55 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 7ae2eb99076..8daa8223584 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -84,6 +84,7 @@ bool wg_parser_stream_get_buffer(struct wg_parser_stream *stream, struct wg_pars
 bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
         void *data, uint32_t offset, uint32_t size);
 void wg_parser_stream_release_buffer(struct wg_parser_stream *stream);
+bool wg_parser_stream_read_data(struct wg_parser_stream *stream, struct wg_sample *sample);
 void wg_parser_stream_notify_qos(struct wg_parser_stream *stream,
         bool underflow, double proportion, int64_t diff, uint64_t timestamp);
 
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 5075b3118cd..23153137bd9 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -235,6 +235,19 @@ void wg_parser_stream_release_buffer(struct wg_parser_stream *stream)
     __wine_unix_call(unix_handle, unix_wg_parser_stream_release_buffer, stream);
 }
 
+bool wg_parser_stream_read_data(struct wg_parser_stream *stream, struct wg_sample *sample)
+{
+    struct wg_parser_stream_read_data_params params =
+    {
+        .stream = stream,
+        .sample = sample,
+    };
+
+    TRACE("stream %p, sample %p.\n", stream, sample);
+
+    return !__wine_unix_call(unix_handle, unix_wg_parser_stream_read_data, &params);
+}
+
 void wg_parser_stream_notify_qos(struct wg_parser_stream *stream,
         bool underflow, double proportion, int64_t diff, uint64_t timestamp)
 {
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index f07b83f413e..1c5518d53d2 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -451,78 +451,53 @@ static void dispatch_end_of_presentation(struct media_source *source)
     IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MEEndOfPresentation, &GUID_NULL, S_OK, &empty);
 }
 
-static void send_buffer(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token)
+static HRESULT mf_allocate_sample(UINT32 size, IMFSample **sample)
 {
     IMFMediaBuffer *buffer;
-    IMFSample *sample;
     HRESULT hr;
-    BYTE *data;
 
-    if (FAILED(hr = MFCreateSample(&sample)))
-    {
-        ERR("Failed to create sample, hr %#lx.\n", hr);
-        return;
-    }
-
-    if (FAILED(hr = MFCreateMemoryBuffer(wg_buffer->size, &buffer)))
-    {
-        ERR("Failed to create buffer, hr %#lx.\n", hr);
-        IMFSample_Release(sample);
-        return;
-    }
+    if (FAILED(hr = MFCreateSample(sample)))
+        return hr;
 
-    if (FAILED(hr = IMFSample_AddBuffer(sample, buffer)))
+    if (SUCCEEDED(hr = MFCreateMemoryBuffer(size, &buffer)))
     {
-        ERR("Failed to add buffer, hr %#lx.\n", hr);
-        goto out;
+        hr = IMFSample_AddBuffer(*sample, buffer);
+        IMFMediaBuffer_Release(buffer);
     }
 
-    if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, wg_buffer->size)))
-    {
-        ERR("Failed to set size, hr %#lx.\n", hr);
-        goto out;
-    }
+    return hr;
+}
 
-    if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL)))
-    {
-        ERR("Failed to lock buffer, hr %#lx.\n", hr);
-        goto out;
-    }
+static void send_buffer(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token)
+{
+    struct wg_sample *wg_sample;
+    IMFSample *sample;
+    bool success;
+    HRESULT hr;
 
-    if (!wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, wg_buffer->size))
+    if (FAILED(hr = mf_allocate_sample(wg_buffer->size, &sample)))
     {
-        wg_parser_stream_release_buffer(stream->wg_stream);
-        IMFMediaBuffer_Unlock(buffer);
-        goto out;
+        ERR("Failed to create sample, hr %#lx.\n", hr);
+        return;
     }
-    wg_parser_stream_release_buffer(stream->wg_stream);
-
-    if (FAILED(hr = IMFMediaBuffer_Unlock(buffer)))
+    if (FAILED(hr = wg_sample_wrap_mf(sample, &wg_sample)))
     {
-        ERR("Failed to unlock buffer, hr %#lx.\n", hr);
-        goto out;
+        ERR("Failed to create sample, hr %#lx.\n", hr);
+        IMFSample_Release(sample);
+        return;
     }
 
-    if (FAILED(hr = IMFSample_SetSampleTime(sample, wg_buffer->pts)))
-    {
-        ERR("Failed to set sample time, hr %#lx.\n", hr);
-        goto out;
-    }
+    success = wg_parser_stream_read_data(stream->wg_stream, wg_sample);
+    wg_sample_unwrap(wg_sample);
 
-    if (FAILED(hr = IMFSample_SetSampleDuration(sample, wg_buffer->duration)))
+    if (success)
     {
-        ERR("Failed to set sample duration, hr %#lx.\n", hr);
-        goto out;
+        if (token)
+            IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token);
+        IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample,
+                &GUID_NULL, S_OK, (IUnknown *)sample);
     }
 
-    if (token)
-        IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token);
-
-    IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample,
-            &GUID_NULL, S_OK, (IUnknown *)sample);
-
-out:
-    IMFMediaBuffer_Release(buffer);
     IMFSample_Release(sample);
 }
 
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h
index 7bce8263aaf..c83aabb59e6 100644
--- a/dlls/winegstreamer/unix_private.h
+++ b/dlls/winegstreamer/unix_private.h
@@ -37,4 +37,7 @@ extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN;
 extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN;
 extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
 
+extern NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align,
+        struct wg_sample *sample) DECLSPEC_HIDDEN;
+
 #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index f334a168bd1..79926042f3c 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -217,6 +217,12 @@ struct wg_parser_stream_copy_buffer_params
     UINT32 size;
 };
 
+struct wg_parser_stream_read_data_params
+{
+    struct wg_parser_stream *stream;
+    struct wg_sample *sample;
+};
+
 struct wg_parser_stream_notify_qos_params
 {
     struct wg_parser_stream *stream;
@@ -283,6 +289,7 @@ enum unix_funcs
     unix_wg_parser_stream_get_buffer,
     unix_wg_parser_stream_copy_buffer,
     unix_wg_parser_stream_release_buffer,
+    unix_wg_parser_stream_read_data,
     unix_wg_parser_stream_notify_qos,
 
     unix_wg_parser_stream_get_duration,
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 6b1a98c0e7d..c949108f8eb 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -350,6 +350,35 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args)
     return S_OK;
 }
 
+static NTSTATUS wg_parser_stream_read_data(void *args)
+{
+    struct wg_parser_stream_read_data_params *params = args;
+    struct wg_parser_stream *stream = params->stream;
+    struct wg_parser *parser = stream->parser;
+    struct wg_sample *sample = params->sample;
+    NTSTATUS status;
+
+    pthread_mutex_lock(&parser->mutex);
+
+    if (!stream->buffer)
+    {
+        pthread_mutex_unlock(&parser->mutex);
+        return VFW_E_WRONG_STATE;
+    }
+
+    status = wg_sample_read_from_buffer(stream->buffer, NULL, 0, sample);
+    if (!(sample->flags & WG_SAMPLE_FLAG_INCOMPLETE))
+    {
+        gst_buffer_unref(stream->buffer);
+        stream->buffer = NULL;
+        pthread_cond_signal(&stream->event_empty_cond);
+    }
+
+    pthread_mutex_unlock(&parser->mutex);
+
+    return status;
+}
+
 static NTSTATUS wg_parser_stream_get_duration(void *args)
 {
     struct wg_parser_stream_get_duration_params *params = args;
@@ -1617,6 +1646,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
     X(wg_parser_stream_get_buffer),
     X(wg_parser_stream_copy_buffer),
     X(wg_parser_stream_release_buffer),
+    X(wg_parser_stream_read_data),
     X(wg_parser_stream_notify_qos),
 
     X(wg_parser_stream_get_duration),
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index fb852b4cf3d..7f0d74340db 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -611,7 +611,7 @@ static bool copy_buffer(GstBuffer *buffer, GstCaps *caps, struct wg_sample *samp
     return true;
 }
 
-static NTSTATUS read_transform_output_data(GstBuffer *buffer, GstCaps *caps, gsize plane_align,
+NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align,
         struct wg_sample *sample)
 {
     gsize total_size;
@@ -725,7 +725,7 @@ NTSTATUS wg_transform_read_data(void *args)
         return STATUS_SUCCESS;
     }
 
-    if ((status = read_transform_output_data(output_buffer, output_caps,
+    if ((status = wg_sample_read_from_buffer(output_buffer, output_caps,
                 transform->output_plane_align, sample)))
         return status;
 
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/179



More information about the wine-devel mailing list