[PATCH v2 3/6] winegstreamer: Introduce new wg_sample_create_quartz helper for quartz_transform.c.

Rémi Bernon wine at gitlab.winehq.org
Mon Jun 13 08:13:59 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/quartz_transform.c | 40 ++++++++++----------
 dlls/winegstreamer/wg_sample.c        | 54 +++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index da76452fbf4..21bd4f25028 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -127,6 +127,7 @@ 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_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);
 
 HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample,
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
index b701b3f6369..2dd7d038f2f 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -290,7 +290,7 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i
 static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSample *sample)
 {
     struct transform *filter = impl_from_strmbase_filter(pin->pin.filter);
-    struct wg_sample input_wg_sample = {0};
+    struct wg_sample *wg_sample;
     REFERENCE_TIME start_time;
     REFERENCE_TIME end_time;
     HRESULT hr;
@@ -311,50 +311,47 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
     if (filter->sink.flushing)
         return S_FALSE;
 
-    input_wg_sample.max_size = IMediaSample_GetSize(sample);
-    input_wg_sample.size = IMediaSample_GetActualDataLength(sample);
-
-    hr = IMediaSample_GetPointer(sample, &input_wg_sample.data);
+    hr = wg_sample_create_quartz(sample, &wg_sample);
     if (FAILED(hr))
         return hr;
 
     hr = IMediaSample_GetTime(sample, &start_time, &end_time);
     if (SUCCEEDED(hr))
     {
-        input_wg_sample.pts = start_time;
-        input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
+        wg_sample->pts = start_time;
+        wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS;
     }
     if (hr == S_OK)
     {
-        input_wg_sample.duration = end_time - start_time;
-        input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
+        wg_sample->duration = end_time - start_time;
+        wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION;
     }
 
-    hr = wg_transform_push_data(filter->transform, &input_wg_sample);
+    hr = wg_transform_push_data(filter->transform, wg_sample);
+    wg_sample_release(wg_sample);
+
     if (FAILED(hr))
         return hr;
 
     for (;;)
     {
-        struct wg_sample output_wg_sample = {0};
         IMediaSample *output_sample;
 
         hr = IMemAllocator_GetBuffer(filter->source.pAllocator, &output_sample, NULL, NULL, 0);
         if (FAILED(hr))
             return hr;
 
-        output_wg_sample.max_size = IMediaSample_GetSize(output_sample);
-
-        hr = IMediaSample_GetPointer(output_sample, &output_wg_sample.data);
+        hr = wg_sample_create_quartz(output_sample, &wg_sample);
         if (FAILED(hr))
         {
             IMediaSample_Release(output_sample);
             return hr;
         }
 
-        hr = wg_transform_read_data(filter->transform, &output_wg_sample, NULL);
+        hr = wg_transform_read_data(filter->transform, wg_sample, NULL);
         if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
         {
+            wg_sample_release(wg_sample);
             IMediaSample_Release(output_sample);
             break;
         }
@@ -362,23 +359,25 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
         {
             if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
                 FIXME("Unexpected stream format change!\n");
+            wg_sample_release(wg_sample);
             IMediaSample_Release(output_sample);
             return hr;
         }
 
-        hr = IMediaSample_SetActualDataLength(output_sample, output_wg_sample.size);
+        hr = IMediaSample_SetActualDataLength(output_sample, wg_sample->size);
         if (FAILED(hr))
         {
+            wg_sample_release(wg_sample);
             IMediaSample_Release(output_sample);
             return hr;
         }
 
-        if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_PTS)
+        if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
         {
-            start_time = output_wg_sample.pts;
-            if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_DURATION)
+            start_time = wg_sample->pts;
+            if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)
             {
-                end_time = start_time + output_wg_sample.duration;
+                end_time = start_time + wg_sample->duration;
                 IMediaSample_SetTime(output_sample, &start_time, &end_time);
             }
             else
@@ -386,6 +385,7 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
                 IMediaSample_SetTime(output_sample, &start_time, NULL);
             }
         }
+        wg_sample_release(wg_sample);
 
         hr = IMemInputPin_Receive(filter->source.pMemInputPin, output_sample);
         if (FAILED(hr))
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
index cf57bdd996b..dded264b079 100644
--- a/dlls/winegstreamer/wg_sample.c
+++ b/dlls/winegstreamer/wg_sample.c
@@ -25,6 +25,7 @@
 #include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+WINE_DECLARE_DEBUG_CHANNEL(quartz);
 
 struct wg_sample_queue
 {
@@ -51,6 +52,10 @@ struct sample
             IMFSample *sample;
             IMFMediaBuffer *buffer;
         } mf;
+        struct
+        {
+            IMediaSample *sample;
+        } quartz;
     } u;
 };
 
@@ -110,6 +115,55 @@ fail:
     return hr;
 }
 
+static const struct wg_sample_ops quartz_sample_ops;
+
+static inline struct sample *unsafe_quartz_from_wg_sample(struct wg_sample *wg_sample)
+{
+    struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+    if (sample->ops != &quartz_sample_ops) return NULL;
+    return sample;
+}
+
+static void quartz_sample_destroy(struct wg_sample *wg_sample)
+{
+    struct sample *sample = unsafe_quartz_from_wg_sample(wg_sample);
+
+    TRACE_(quartz)("wg_sample %p.\n", wg_sample);
+
+    IMediaSample_Release(sample->u.quartz.sample);
+}
+
+static const struct wg_sample_ops quartz_sample_ops =
+{
+    quartz_sample_destroy,
+};
+
+HRESULT wg_sample_create_quartz(IMediaSample *media_sample, struct wg_sample **out)
+{
+    DWORD current_length, max_length;
+    struct sample *sample;
+    BYTE *buffer;
+    HRESULT hr;
+
+    if (FAILED(hr = IMediaSample_GetPointer(media_sample, &buffer)))
+        return hr;
+    current_length = IMediaSample_GetActualDataLength(media_sample);
+    max_length = IMediaSample_GetSize(media_sample);
+
+    if (!(sample = calloc(1, sizeof(*sample))))
+        return E_OUTOFMEMORY;
+
+    IMediaSample_AddRef((sample->u.quartz.sample = media_sample));
+    sample->wg_sample.data = buffer;
+    sample->wg_sample.size = current_length;
+    sample->wg_sample.max_size = max_length;
+    sample->ops = &quartz_sample_ops;
+
+    TRACE_(quartz)("Created wg_sample %p for IMediaSample %p.\n", &sample->wg_sample, media_sample);
+    *out = &sample->wg_sample;
+    return S_OK;
+}
+
 void wg_sample_release(struct wg_sample *wg_sample)
 {
     struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
-- 
GitLab


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



More information about the wine-devel mailing list