Commit b2828c1c authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winegstreamer: Use a union in struct sample to keep API pointers.

parent 57b3b292
...@@ -32,12 +32,51 @@ struct wg_sample_queue ...@@ -32,12 +32,51 @@ struct wg_sample_queue
struct list samples; struct list samples;
}; };
struct wg_sample_ops
{
void (*destroy)(struct wg_sample *sample);
};
struct sample struct sample
{ {
IMFSample *sample;
IMFMediaBuffer *media_buffer;
struct wg_sample wg_sample; struct wg_sample wg_sample;
const struct wg_sample_ops *ops;
struct list entry; 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) 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) ...@@ -49,23 +88,24 @@ HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out)
if (!(sample = calloc(1, sizeof(*sample)))) if (!(sample = calloc(1, sizeof(*sample))))
return E_OUTOFMEMORY; 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; goto fail;
if (FAILED(hr = IMFMediaBuffer_Lock(sample->media_buffer, &buffer, &max_length, &current_length))) if (FAILED(hr = IMFMediaBuffer_Lock(sample->u.mf.buffer, &buffer, &max_length, &current_length)))
goto fail; goto fail;
IMFSample_AddRef((sample->sample = mf_sample)); IMFSample_AddRef((sample->u.mf.sample = mf_sample));
sample->wg_sample.data = buffer; sample->wg_sample.data = buffer;
sample->wg_sample.size = current_length; sample->wg_sample.size = current_length;
sample->wg_sample.max_size = max_length; sample->wg_sample.max_size = max_length;
sample->ops = &mf_sample_ops;
*out = &sample->wg_sample; *out = &sample->wg_sample;
TRACE_(mfplat)("Created wg_sample %p for IMFSample %p.\n", *out, mf_sample); TRACE_(mfplat)("Created wg_sample %p for IMFSample %p.\n", *out, mf_sample);
return S_OK; return S_OK;
fail: fail:
if (sample->media_buffer) if (sample->u.mf.buffer)
IMFMediaBuffer_Release(sample->media_buffer); IMFMediaBuffer_Release(sample->u.mf.buffer);
free(sample); free(sample);
return hr; return hr;
} }
...@@ -80,9 +120,7 @@ void wg_sample_release(struct wg_sample *wg_sample) ...@@ -80,9 +120,7 @@ void wg_sample_release(struct wg_sample *wg_sample)
return; return;
} }
IMFMediaBuffer_Unlock(sample->media_buffer); sample->ops->destroy(wg_sample);
IMFMediaBuffer_Release(sample->media_buffer);
IMFSample_Release(sample->sample);
free(sample); free(sample);
} }
...@@ -156,22 +194,24 @@ void wg_sample_queue_destroy(struct wg_sample_queue *queue) ...@@ -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, HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
struct wg_sample_queue *queue) 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; LONGLONG time, duration;
UINT32 value; UINT32 value;
HRESULT hr; 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.flags |= WG_SAMPLE_FLAG_HAS_PTS;
sample->wg_sample.pts = time; 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.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
sample->wg_sample.duration = 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; sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
wg_sample_queue_begin_append(queue, wg_sample); 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 ...@@ -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, HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
struct wg_format *format) 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; 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))) if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
return hr; 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) 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) 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) 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; return S_OK;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment