[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, ¤t_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