[PATCH v2 2/6] winegstreamer: Use a union in struct sample to keep API pointers.
Rémi Bernon
wine at gitlab.winehq.org
Mon Jun 13 08:13:58 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winegstreamer/wg_sample.c | 81 ++++++++++++++++++++++++++--------
1 file changed, 62 insertions(+), 19 deletions(-)
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
index 051e6199ec9..cf57bdd996b 100644
--- a/dlls/winegstreamer/wg_sample.c
+++ b/dlls/winegstreamer/wg_sample.c
@@ -32,12 +32,51 @@ struct wg_sample_queue
struct list samples;
};
+struct wg_sample_ops
+{
+ void (*destroy)(struct wg_sample *sample);
+};
+
struct sample
{
- IMFSample *sample;
- IMFMediaBuffer *media_buffer;
struct wg_sample wg_sample;
+
+ const struct wg_sample_ops *ops;
struct list entry;
+
+ union
+ {
+ struct
+ {
+ IMFSample *sample;
+ IMFMediaBuffer *buffer;
+ } mf;
+ } u;
+};
+
+static const struct wg_sample_ops mf_sample_ops;
+
+static inline struct sample *unsafe_mf_from_wg_sample(struct wg_sample *wg_sample)
+{
+ struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
+ if (sample->ops != &mf_sample_ops) return NULL;
+ return sample;
+}
+
+static void mf_sample_destroy(struct wg_sample *wg_sample)
+{
+ struct sample *sample = unsafe_mf_from_wg_sample(wg_sample);
+
+ TRACE_(mfplat)("wg_sample %p.\n", wg_sample);
+
+ IMFMediaBuffer_Unlock(sample->u.mf.buffer);
+ IMFMediaBuffer_Release(sample->u.mf.buffer);
+ IMFSample_Release(sample->u.mf.sample);
+}
+
+static const struct wg_sample_ops mf_sample_ops =
+{
+ mf_sample_destroy,
};
HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out)
@@ -49,23 +88,24 @@ HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out)
if (!(sample = calloc(1, sizeof(*sample))))
return E_OUTOFMEMORY;
- if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(mf_sample, &sample->media_buffer)))
+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(mf_sample, &sample->u.mf.buffer)))
goto fail;
- if (FAILED(hr = IMFMediaBuffer_Lock(sample->media_buffer, &buffer, &max_length, ¤t_length)))
+ if (FAILED(hr = IMFMediaBuffer_Lock(sample->u.mf.buffer, &buffer, &max_length, ¤t_length)))
goto fail;
- IMFSample_AddRef((sample->sample = mf_sample));
+ IMFSample_AddRef((sample->u.mf.sample = mf_sample));
sample->wg_sample.data = buffer;
sample->wg_sample.size = current_length;
sample->wg_sample.max_size = max_length;
+ sample->ops = &mf_sample_ops;
*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);
+ if (sample->u.mf.buffer)
+ IMFMediaBuffer_Release(sample->u.mf.buffer);
free(sample);
return hr;
}
@@ -80,9 +120,7 @@ void wg_sample_release(struct wg_sample *wg_sample)
return;
}
- IMFMediaBuffer_Unlock(sample->media_buffer);
- IMFMediaBuffer_Release(sample->media_buffer);
- IMFSample_Release(sample->sample);
+ sample->ops->destroy(wg_sample);
free(sample);
}
@@ -156,22 +194,24 @@ void wg_sample_queue_destroy(struct wg_sample_queue *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);
+ struct sample *sample = unsafe_mf_from_wg_sample(wg_sample);
LONGLONG time, duration;
UINT32 value;
HRESULT hr;
- if (SUCCEEDED(IMFSample_GetSampleTime(sample->sample, &time)))
+ TRACE_(mfplat)("transform %p, wg_sample %p, queue %p.\n", transform, wg_sample, queue);
+
+ if (SUCCEEDED(IMFSample_GetSampleTime(sample->u.mf.sample, &time)))
{
sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
sample->wg_sample.pts = time;
}
- if (SUCCEEDED(IMFSample_GetSampleDuration(sample->sample, &duration)))
+ if (SUCCEEDED(IMFSample_GetSampleDuration(sample->u.mf.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)
+ if (SUCCEEDED(IMFSample_GetUINT32(sample->u.mf.sample, &MFSampleExtension_CleanPoint, &value)) && value)
sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
wg_sample_queue_begin_append(queue, wg_sample);
@@ -184,20 +224,23 @@ HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *w
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);
+ struct sample *sample = unsafe_mf_from_wg_sample(wg_sample);
HRESULT hr;
+ TRACE_(mfplat)("transform %p, wg_sample %p, format %p.\n", transform, wg_sample, format);
+
if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
return hr;
- IMFMediaBuffer_SetCurrentLength(sample->media_buffer, wg_sample->size);
+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(sample->u.mf.buffer, wg_sample->size)))
+ return hr;
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
- IMFSample_SetSampleTime(sample->sample, wg_sample->pts);
+ IMFSample_SetSampleTime(sample->u.mf.sample, wg_sample->pts);
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)
- IMFSample_SetSampleDuration(sample->sample, wg_sample->duration);
+ IMFSample_SetSampleDuration(sample->u.mf.sample, wg_sample->duration);
if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)
- IMFSample_SetUINT32(sample->sample, &MFSampleExtension_CleanPoint, 1);
+ IMFSample_SetUINT32(sample->u.mf.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