[PATCH 4/6] winegstreamer: Read wm_reader stream data using wg_sample struct.

Rémi Bernon wine at gitlab.winehq.org
Fri Jun 3 04:17:13 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  |  2 ++
 dlls/winegstreamer/unixlib.h      |  1 +
 dlls/winegstreamer/wg_sample.c    | 48 +++++++++++++++++++++++++
 dlls/winegstreamer/wg_transform.c |  4 +++
 dlls/winegstreamer/wm_reader.c    | 58 ++++++++++++++-----------------
 5 files changed, 81 insertions(+), 32 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 8daa8223584..8fb1bdf9576 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -122,6 +122,8 @@ 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_wrap_mf(IMFSample *mf_sample, struct wg_sample **out);
+HRESULT wg_sample_wrap_wm(INSSBuffer *wm_sample, QWORD pts, QWORD duration, DWORD flags,
+        struct wg_sample **out);
 void wg_sample_unwrap(struct wg_sample *wg_sample);
 
 HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj);
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index 79926042f3c..7e639abfd3c 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -121,6 +121,7 @@ enum wg_sample_flag
     WG_SAMPLE_FLAG_HAS_PTS = 2,
     WG_SAMPLE_FLAG_HAS_DURATION = 4,
     WG_SAMPLE_FLAG_SYNC_POINT = 8,
+    WG_SAMPLE_FLAG_DISCONTINUITY = 0x10,
 };
 
 struct wg_sample
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
index e20e393e396..fd757fa44f6 100644
--- a/dlls/winegstreamer/wg_sample.c
+++ b/dlls/winegstreamer/wg_sample.c
@@ -24,6 +24,7 @@
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+WINE_DECLARE_DEBUG_CHANNEL(wmvcore);
 
 struct sample
 {
@@ -31,6 +32,7 @@ struct sample
     enum wg_sample_type
     {
         WG_SAMPLE_TYPE_MF = 1,
+        WG_SAMPLE_TYPE_WM = 2,
     } type;
 
     union
@@ -40,6 +42,10 @@ struct sample
             IMFSample *sample;
             IMFMediaBuffer *buffer;
         } mf;
+        struct
+        {
+            INSSBuffer *sample;
+        } wm;
     } u;
 };
 
@@ -89,6 +95,41 @@ failed:
     return hr;
 }
 
+HRESULT wg_sample_wrap_wm(INSSBuffer *wm_sample, QWORD pts, QWORD duration, DWORD flags,
+        struct wg_sample **out)
+{
+    DWORD current_length, max_length;
+    struct sample *sample;
+    BYTE *buffer;
+    HRESULT hr;
+
+    if (FAILED(hr = INSSBuffer_GetBufferAndLength(wm_sample, &buffer, &current_length)))
+        return hr;
+    if (FAILED(hr = INSSBuffer_GetMaxLength(wm_sample, &max_length)))
+        return hr;
+    if (!(sample = calloc(1, sizeof(*sample))))
+        return E_OUTOFMEMORY;
+
+    if ((sample->wg_sample.pts = pts) != ~(QWORD)0)
+        sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
+    if ((sample->wg_sample.duration = duration) != ~(QWORD)0)
+        sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
+    if (flags & WM_SF_CLEANPOINT)
+        sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
+    if (flags & WM_SF_DISCONTINUITY)
+        sample->wg_sample.flags |= WG_SAMPLE_FLAG_DISCONTINUITY;
+
+    INSSBuffer_AddRef((sample->u.wm.sample = wm_sample));
+    sample->wg_sample.data = buffer;
+    sample->wg_sample.size = current_length;
+    sample->wg_sample.max_size = max_length;
+    sample->type = WG_SAMPLE_TYPE_WM;
+
+    TRACE_(wmvcore)("Created wg_sample %p for sample %p.\n", &sample->wg_sample, wm_sample);
+    *out = &sample->wg_sample;
+    return S_OK;
+}
+
 void wg_sample_unwrap(struct wg_sample *wg_sample)
 {
     struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
@@ -112,6 +153,13 @@ void wg_sample_unwrap(struct wg_sample *wg_sample)
             IMFSample_Release(sample->u.mf.sample);
             break;
 
+        case WG_SAMPLE_TYPE_WM:
+            TRACE_(wmvcore)("wg_sample %p\n", wg_sample);
+
+            INSSBuffer_SetLength(sample->u.wm.sample, wg_sample->size);
+            INSSBuffer_Release(sample->u.wm.sample);
+            break;
+
         default:
             FIXME("Unknown wg_sample %p, type %u\n", wg_sample, sample->type);
             break;
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 7f0d74340db..bd53c13e84b 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -523,6 +523,8 @@ NTSTATUS wg_transform_push_data(void *args)
         GST_BUFFER_DURATION(buffer) = sample->duration * 100;
     if (!(sample->flags & WG_SAMPLE_FLAG_SYNC_POINT))
         GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+    if (sample->flags & WG_SAMPLE_FLAG_DISCONTINUITY)
+        GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DISCONT);
     gst_buffer_list_insert(transform->input, -1, buffer);
 
     GST_INFO("Copied %u bytes from sample %p to input buffer list", sample->size, sample);
@@ -648,6 +650,8 @@ NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plan
     }
     if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT))
         sample->flags |= WG_SAMPLE_FLAG_SYNC_POINT;
+    if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT))
+        sample->flags |= WG_SAMPLE_FLAG_DISCONTINUITY;
 
     GST_INFO("Copied %u bytes, sample %p, flags %#x", sample->size, sample, sample->flags);
     return STATUS_SUCCESS;
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 03adea8a318..72a2d207c57 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1877,11 +1877,11 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
     IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced;
     struct wg_parser_stream *wg_stream;
     struct wg_parser_buffer wg_buffer;
+    struct wg_sample *wg_sample;
     struct wm_stream *stream;
-    DWORD size, capacity;
     INSSBuffer *sample;
+    bool success;
     HRESULT hr;
-    BYTE *data;
 
     for (;;)
     {
@@ -1930,7 +1930,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
                     stream->index + 1, wg_buffer.size, &sample, NULL)))
             {
                 ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr);
-                wg_parser_stream_release_buffer(wg_stream);
                 return hr;
             }
         }
@@ -1940,7 +1939,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
                     stream->index, wg_buffer.size, &sample, NULL)))
             {
                 ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr);
-                wg_parser_stream_release_buffer(wg_stream);
                 return hr;
             }
         }
@@ -1950,10 +1948,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
 
             /* FIXME: Should these be pooled? */
             if (!(object = calloc(1, offsetof(struct buffer, data[wg_buffer.size]))))
-            {
-                wg_parser_stream_release_buffer(wg_stream);
                 return E_OUTOFMEMORY;
-            }
 
             object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
             object->refcount = 1;
@@ -1963,38 +1958,37 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
             sample = &object->INSSBuffer_iface;
         }
 
-        if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size)))
-            ERR("Failed to get data pointer, hr %#lx.\n", hr);
-        if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
-            ERR("Failed to get capacity, hr %#lx.\n", hr);
-        if (wg_buffer.size > capacity)
-            ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, wg_buffer.size);
+        if (FAILED(hr = wg_sample_wrap_wm(sample, ~(QWORD)0, ~(QWORD)0, 0, &wg_sample)))
+        {
+            ERR("Failed to create wg_sample, hr %#lx.\n", hr);
+            INSSBuffer_Release(sample);
+            return hr;
+        }
 
-        if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, wg_buffer.size))
+        if ((success = wg_parser_stream_read_data(wg_stream, wg_sample)))
+        {
+            if (!(wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS))
+                FIXME("Missing PTS.\n");
+            if (!(wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION))
+                FIXME("Missing duration.\n");
+
+            *pts = wg_sample->pts;
+            *duration = wg_sample->duration;
+            *flags = 0;
+            if (wg_sample->flags & WG_SAMPLE_FLAG_DISCONTINUITY)
+                *flags |= WM_SF_DISCONTINUITY;
+            if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)
+                *flags |= WM_SF_CLEANPOINT;
+        }
+        wg_sample_unwrap(wg_sample);
+
+        if (!success)
         {
             /* The GStreamer pin has been flushed. */
             INSSBuffer_Release(sample);
             continue;
         }
 
-        if (FAILED(hr = INSSBuffer_SetLength(sample, wg_buffer.size)))
-            ERR("Failed to set size %u, hr %#lx.\n", wg_buffer.size, hr);
-
-        wg_parser_stream_release_buffer(wg_stream);
-
-        if (!wg_buffer.has_pts)
-            FIXME("Missing PTS.\n");
-        if (!wg_buffer.has_duration)
-            FIXME("Missing duration.\n");
-
-        *pts = wg_buffer.pts;
-        *duration = wg_buffer.duration;
-        *flags = 0;
-        if (wg_buffer.discontinuity)
-            *flags |= WM_SF_DISCONTINUITY;
-        if (!wg_buffer.delta)
-            *flags |= WM_SF_CLEANPOINT;
-
         *ret_sample = sample;
         *ret_stream_number = stream_number;
         return S_OK;
-- 
GitLab


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



More information about the wine-devel mailing list