[PATCH v2 1/6] winegstreamer: Split wg_sample wrapper helpers to a separate source.
Rémi Bernon
wine at gitlab.winehq.org
Mon Jun 13 08:13:57 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/mfplat.c | 176 ----------------------------
dlls/winegstreamer/wg_sample.c | 203 +++++++++++++++++++++++++++++++++
3 files changed, 204 insertions(+), 176 deletions(-)
create mode 100644 dlls/winegstreamer/wg_sample.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index 50f4dc861d4..6e3517dcb36 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -17,6 +17,7 @@ C_SRCS = \
wg_allocator.c \
wg_format.c \
wg_parser.c \
+ wg_sample.c \
wg_transform.c \
wm_asyncreader.c \
wm_reader.c \
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 157ed3ad2f2..c5ca4b15c0f 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -958,179 +958,3 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
else
FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));
}
-
-struct wg_sample_queue
-{
- CRITICAL_SECTION cs;
- struct list samples;
-};
-
-struct mf_sample
-{
- IMFSample *sample;
- IMFMediaBuffer *media_buffer;
- struct wg_sample wg_sample;
- struct list entry;
-};
-
-HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out)
-{
- DWORD current_length, max_length;
- struct mf_sample *mf_sample;
- BYTE *buffer;
- HRESULT hr;
-
- if (!(mf_sample = calloc(1, sizeof(*mf_sample))))
- return E_OUTOFMEMORY;
- if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &mf_sample->media_buffer)))
- goto out;
- if (FAILED(hr = IMFMediaBuffer_Lock(mf_sample->media_buffer, &buffer, &max_length, ¤t_length)))
- goto out;
-
- IMFSample_AddRef((mf_sample->sample = sample));
- mf_sample->wg_sample.data = buffer;
- mf_sample->wg_sample.size = current_length;
- mf_sample->wg_sample.max_size = max_length;
-
- TRACE("Created mf_sample %p for sample %p.\n", mf_sample, sample);
- *out = &mf_sample->wg_sample;
- return S_OK;
-
-out:
- if (mf_sample->media_buffer)
- IMFMediaBuffer_Release(mf_sample->media_buffer);
- free(mf_sample);
- return hr;
-}
-
-void wg_sample_release(struct wg_sample *wg_sample)
-{
- struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
-
- if (InterlockedOr(&wg_sample->refcount, 0))
- {
- ERR("Sample %p is still in use, trouble ahead!\n", wg_sample);
- return;
- }
-
- IMFMediaBuffer_Unlock(mf_sample->media_buffer);
- IMFMediaBuffer_Release(mf_sample->media_buffer);
- IMFSample_Release(mf_sample->sample);
-
- free(mf_sample);
-}
-
-static void wg_sample_queue_begin_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample)
-{
- struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
-
- /* make sure a concurrent wg_sample_queue_flush call won't release the sample until we're done */
- InterlockedIncrement(&wg_sample->refcount);
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_REFCOUNT;
-
- EnterCriticalSection(&queue->cs);
- list_add_tail(&queue->samples, &mf_sample->entry);
- LeaveCriticalSection(&queue->cs);
-}
-
-static void wg_sample_queue_end_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample)
-{
- /* release temporary ref taken in wg_sample_queue_begin_append */
- InterlockedDecrement(&wg_sample->refcount);
-
- wg_sample_queue_flush(queue, false);
-}
-
-void wg_sample_queue_flush(struct wg_sample_queue *queue, bool all)
-{
- struct mf_sample *mf_sample, *next;
-
- EnterCriticalSection(&queue->cs);
-
- LIST_FOR_EACH_ENTRY_SAFE(mf_sample, next, &queue->samples, struct mf_sample, entry)
- {
- if (!InterlockedOr(&mf_sample->wg_sample.refcount, 0) || all)
- {
- list_remove(&mf_sample->entry);
- wg_sample_release(&mf_sample->wg_sample);
- }
- }
-
- LeaveCriticalSection(&queue->cs);
-}
-
-HRESULT wg_sample_queue_create(struct wg_sample_queue **out)
-{
- struct wg_sample_queue *queue;
-
- if (!(queue = calloc(1, sizeof(*queue))))
- return E_OUTOFMEMORY;
-
- InitializeCriticalSection(&queue->cs);
- queue->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
- list_init(&queue->samples);
-
- TRACE("Created sample queue %p\n", queue);
- *out = queue;
-
- return S_OK;
-}
-
-void wg_sample_queue_destroy(struct wg_sample_queue *queue)
-{
- wg_sample_queue_flush(queue, true);
-
- queue->cs.DebugInfo->Spare[0] = 0;
- InitializeCriticalSection(&queue->cs);
-
- free(queue);
-}
-
-HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
- struct wg_sample_queue *queue)
-{
- struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
- LONGLONG time, duration;
- UINT32 value;
- HRESULT hr;
-
- if (SUCCEEDED(IMFSample_GetSampleTime(mf_sample->sample, &time)))
- {
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
- mf_sample->wg_sample.pts = time;
- }
- if (SUCCEEDED(IMFSample_GetSampleDuration(mf_sample->sample, &duration)))
- {
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
- mf_sample->wg_sample.duration = duration;
- }
- if (SUCCEEDED(IMFSample_GetUINT32(mf_sample->sample, &MFSampleExtension_CleanPoint, &value)) && value)
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
-
- wg_sample_queue_begin_append(queue, wg_sample);
- hr = wg_transform_push_data(transform, wg_sample);
- wg_sample_queue_end_append(queue, wg_sample);
-
- return hr;
-}
-
-HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
- struct wg_format *format)
-{
- struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
- HRESULT hr;
-
- if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
- return hr;
-
- IMFMediaBuffer_SetCurrentLength(mf_sample->media_buffer, wg_sample->size);
-
- if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
- IMFSample_SetSampleTime(mf_sample->sample, wg_sample->pts);
- if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)
- IMFSample_SetSampleDuration(mf_sample->sample, wg_sample->duration);
- if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)
- IMFSample_SetUINT32(mf_sample->sample, &MFSampleExtension_CleanPoint, 1);
-
- return S_OK;
-}
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
new file mode 100644
index 00000000000..051e6199ec9
--- /dev/null
+++ b/dlls/winegstreamer/wg_sample.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2022 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "gst_private.h"
+
+#include "wmcodecdsp.h"
+#include "mfapi.h"
+
+#include "wine/debug.h"
+#include "wine/list.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+struct wg_sample_queue
+{
+ CRITICAL_SECTION cs;
+ struct list samples;
+};
+
+struct sample
+{
+ IMFSample *sample;
+ IMFMediaBuffer *media_buffer;
+ struct wg_sample wg_sample;
+ struct list entry;
+};
+
+HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out)
+{
+ DWORD current_length, max_length;
+ struct sample *sample;
+ BYTE *buffer;
+ HRESULT hr;
+
+ if (!(sample = calloc(1, sizeof(*sample))))
+ return E_OUTOFMEMORY;
+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(mf_sample, &sample->media_buffer)))
+ goto fail;
+ if (FAILED(hr = IMFMediaBuffer_Lock(sample->media_buffer, &buffer, &max_length, ¤t_length)))
+ goto fail;
+
+ IMFSample_AddRef((sample->sample = mf_sample));
+ sample->wg_sample.data = buffer;
+ sample->wg_sample.size = current_length;
+ sample->wg_sample.max_size = max_length;
+
+ *out = &sample->wg_sample;
+ TRACE_(mfplat)("Created wg_sample %p for IMFSample %p.\n", *out, mf_sample);
+ return S_OK;
+
+fail:
+ if (sample->media_buffer)
+ IMFMediaBuffer_Release(sample->media_buffer);
+ free(sample);
+ return hr;
+}
+
+void wg_sample_release(struct wg_sample *wg_sample)
+{
+ struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+
+ if (InterlockedOr(&wg_sample->refcount, 0))
+ {
+ ERR("wg_sample %p is still in use, trouble ahead!\n", wg_sample);
+ return;
+ }
+
+ IMFMediaBuffer_Unlock(sample->media_buffer);
+ IMFMediaBuffer_Release(sample->media_buffer);
+ IMFSample_Release(sample->sample);
+
+ free(sample);
+}
+
+static void wg_sample_queue_begin_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample)
+{
+ struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+
+ /* make sure a concurrent wg_sample_queue_flush call won't release the sample until we're done */
+ InterlockedIncrement(&wg_sample->refcount);
+ sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_REFCOUNT;
+
+ EnterCriticalSection(&queue->cs);
+ list_add_tail(&queue->samples, &sample->entry);
+ LeaveCriticalSection(&queue->cs);
+}
+
+static void wg_sample_queue_end_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample)
+{
+ /* release temporary ref taken in wg_sample_queue_begin_append */
+ InterlockedDecrement(&wg_sample->refcount);
+
+ wg_sample_queue_flush(queue, false);
+}
+
+void wg_sample_queue_flush(struct wg_sample_queue *queue, bool all)
+{
+ struct sample *sample, *next;
+
+ EnterCriticalSection(&queue->cs);
+
+ LIST_FOR_EACH_ENTRY_SAFE(sample, next, &queue->samples, struct sample, entry)
+ {
+ if (!InterlockedOr(&sample->wg_sample.refcount, 0) || all)
+ {
+ list_remove(&sample->entry);
+ wg_sample_release(&sample->wg_sample);
+ }
+ }
+
+ LeaveCriticalSection(&queue->cs);
+}
+
+HRESULT wg_sample_queue_create(struct wg_sample_queue **out)
+{
+ struct wg_sample_queue *queue;
+
+ if (!(queue = calloc(1, sizeof(*queue))))
+ return E_OUTOFMEMORY;
+
+ InitializeCriticalSection(&queue->cs);
+ queue->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
+ list_init(&queue->samples);
+
+ TRACE("Created wg_sample_queue %p.\n", queue);
+ *out = queue;
+
+ return S_OK;
+}
+
+void wg_sample_queue_destroy(struct wg_sample_queue *queue)
+{
+ wg_sample_queue_flush(queue, true);
+
+ queue->cs.DebugInfo->Spare[0] = 0;
+ InitializeCriticalSection(&queue->cs);
+
+ free(queue);
+}
+
+HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
+ struct wg_sample_queue *queue)
+{
+ struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+ LONGLONG time, duration;
+ UINT32 value;
+ HRESULT hr;
+
+ if (SUCCEEDED(IMFSample_GetSampleTime(sample->sample, &time)))
+ {
+ sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
+ sample->wg_sample.pts = time;
+ }
+ if (SUCCEEDED(IMFSample_GetSampleDuration(sample->sample, &duration)))
+ {
+ sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
+ sample->wg_sample.duration = duration;
+ }
+ if (SUCCEEDED(IMFSample_GetUINT32(sample->sample, &MFSampleExtension_CleanPoint, &value)) && value)
+ sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
+
+ wg_sample_queue_begin_append(queue, wg_sample);
+ hr = wg_transform_push_data(transform, wg_sample);
+ wg_sample_queue_end_append(queue, wg_sample);
+
+ return hr;
+}
+
+HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
+ struct wg_format *format)
+{
+ struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+ HRESULT hr;
+
+ if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
+ return hr;
+
+ IMFMediaBuffer_SetCurrentLength(sample->media_buffer, wg_sample->size);
+
+ if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
+ IMFSample_SetSampleTime(sample->sample, wg_sample->pts);
+ if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)
+ IMFSample_SetSampleDuration(sample->sample, wg_sample->duration);
+ if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)
+ IMFSample_SetUINT32(sample->sample, &MFSampleExtension_CleanPoint, 1);
+
+ return S_OK;
+}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/220
More information about the wine-devel
mailing list