From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@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; }