From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@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..8879de6c232 --- /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 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; +}
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/wg_sample.c | 94 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 47 deletions(-)
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 8879de6c232..b7fd9a002a5 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -32,7 +32,7 @@ struct wg_sample_queue struct list samples; };
-struct mf_sample +struct sample { IMFSample *sample; IMFMediaBuffer *media_buffer; @@ -40,39 +40,39 @@ struct mf_sample struct list entry; };
-HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out) +HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out) { DWORD current_length, max_length; - struct mf_sample *mf_sample; + struct sample *sample; BYTE *buffer; HRESULT hr;
- if (!(mf_sample = calloc(1, sizeof(*mf_sample)))) + if (!(sample = calloc(1, sizeof(*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; + 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("Created wg_sample %p for MF sample %p.\n", *out, mf_sample); return S_OK;
-out: - if (mf_sample->media_buffer) - IMFMediaBuffer_Release(mf_sample->media_buffer); - free(mf_sample); +fail: + if (sample->media_buffer) + IMFMediaBuffer_Release(sample->media_buffer); + free(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); + struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
if (InterlockedOr(&wg_sample->refcount, 0)) { @@ -80,23 +80,23 @@ void wg_sample_release(struct wg_sample *wg_sample) return; }
- IMFMediaBuffer_Unlock(mf_sample->media_buffer); - IMFMediaBuffer_Release(mf_sample->media_buffer); - IMFSample_Release(mf_sample->sample); + IMFMediaBuffer_Unlock(sample->media_buffer); + IMFMediaBuffer_Release(sample->media_buffer); + IMFSample_Release(sample->sample);
- free(mf_sample); + free(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); + 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); - mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_REFCOUNT; + sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_REFCOUNT;
EnterCriticalSection(&queue->cs); - list_add_tail(&queue->samples, &mf_sample->entry); + list_add_tail(&queue->samples, &sample->entry); LeaveCriticalSection(&queue->cs); }
@@ -110,16 +110,16 @@ static void wg_sample_queue_end_append(struct wg_sample_queue *queue, struct wg_
void wg_sample_queue_flush(struct wg_sample_queue *queue, bool all) { - struct mf_sample *mf_sample, *next; + struct sample *sample, *next;
EnterCriticalSection(&queue->cs);
- LIST_FOR_EACH_ENTRY_SAFE(mf_sample, next, &queue->samples, struct mf_sample, entry) + LIST_FOR_EACH_ENTRY_SAFE(sample, next, &queue->samples, struct sample, entry) { - if (!InterlockedOr(&mf_sample->wg_sample.refcount, 0) || all) + if (!InterlockedOr(&sample->wg_sample.refcount, 0) || all) { - list_remove(&mf_sample->entry); - wg_sample_release(&mf_sample->wg_sample); + list_remove(&sample->entry); + wg_sample_release(&sample->wg_sample); } }
@@ -156,23 +156,23 @@ 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 mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample); + struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); LONGLONG time, duration; UINT32 value; HRESULT hr;
- if (SUCCEEDED(IMFSample_GetSampleTime(mf_sample->sample, &time))) + if (SUCCEEDED(IMFSample_GetSampleTime(sample->sample, &time))) { - mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS; - mf_sample->wg_sample.pts = time; + sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS; + sample->wg_sample.pts = time; } - if (SUCCEEDED(IMFSample_GetSampleDuration(mf_sample->sample, &duration))) + if (SUCCEEDED(IMFSample_GetSampleDuration(sample->sample, &duration))) { - mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION; - mf_sample->wg_sample.duration = duration; + sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION; + 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; + 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); @@ -184,20 +184,20 @@ 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 mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample); + 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(mf_sample->media_buffer, wg_sample->size); + IMFMediaBuffer_SetCurrentLength(sample->media_buffer, wg_sample->size);
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS) - IMFSample_SetSampleTime(mf_sample->sample, wg_sample->pts); + IMFSample_SetSampleTime(sample->sample, wg_sample->pts); if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION) - IMFSample_SetSampleDuration(mf_sample->sample, wg_sample->duration); + IMFSample_SetSampleDuration(sample->sample, wg_sample->duration); if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT) - IMFSample_SetUINT32(mf_sample->sample, &MFSampleExtension_CleanPoint, 1); + IMFSample_SetUINT32(sample->sample, &MFSampleExtension_CleanPoint, 1);
return S_OK; }
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/wg_sample.c | 64 +++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 17 deletions(-)
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index b7fd9a002a5..017ec706f50 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -34,10 +34,22 @@ struct wg_sample_queue
struct sample { - IMFSample *sample; - IMFMediaBuffer *media_buffer; struct wg_sample wg_sample; struct list entry; + + enum wg_sample_type + { + WG_SAMPLE_TYPE_MF = 1, + } type; + + union + { + struct + { + IMFSample *sample; + IMFMediaBuffer *buffer; + } mf; + } u; };
HRESULT wg_sample_create_mf(IMFSample *mf_sample, struct wg_sample **out) @@ -49,23 +61,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->type = WG_SAMPLE_TYPE_MF;
*out = &sample->wg_sample; TRACE("Created wg_sample %p for MF sample %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 +93,20 @@ void wg_sample_release(struct wg_sample *wg_sample) return; }
- IMFMediaBuffer_Unlock(sample->media_buffer); - IMFMediaBuffer_Release(sample->media_buffer); - IMFSample_Release(sample->sample); + switch (sample->type) + { + case WG_SAMPLE_TYPE_MF: + TRACE("wg_sample %p\n", wg_sample); + + IMFMediaBuffer_Unlock(sample->u.mf.buffer); + IMFMediaBuffer_Release(sample->u.mf.buffer); + IMFSample_Release(sample->u.mf.sample); + break; + + default: + FIXME("Unknown wg_sample %p, type %u\n", wg_sample, sample->type); + break; + }
free(sample); } @@ -161,17 +185,20 @@ HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *w UINT32 value; HRESULT hr;
- if (SUCCEEDED(IMFSample_GetSampleTime(sample->sample, &time))) + if (sample->type != WG_SAMPLE_TYPE_MF) + return E_INVALIDARG; + + 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); @@ -187,17 +214,20 @@ HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *w struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); HRESULT hr;
+ if (sample->type != WG_SAMPLE_TYPE_MF) + return E_INVALIDARG; + if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format))) return hr;
- IMFMediaBuffer_SetCurrentLength(sample->media_buffer, wg_sample->size); + IMFMediaBuffer_SetCurrentLength(sample->u.mf.buffer, wg_sample->size);
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; }
On 6/10/22 02:53, Rémi Bernon wrote:
- switch (sample->type)
- {
case WG_SAMPLE_TYPE_MF:
TRACE("wg_sample %p\n", wg_sample);
IMFMediaBuffer_Unlock(sample->u.mf.buffer);
IMFMediaBuffer_Release(sample->u.mf.buffer);
IMFSample_Release(sample->u.mf.sample);
break;
default:
FIXME("Unknown wg_sample %p, type %u\n", wg_sample, sample->type);
break;
- }
Have you considered using a destruction callback instead (especially since it'd just be the one callback?)
I haven't tried it, so maybe it ends up being less pretty, but it'd at least make it easier to avoid mixing multiple frontends in the same file.
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/quartz_transform.c | 40 +++++++++++++-------------- dlls/winegstreamer/wg_sample.c | 38 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index da76452fbf4..cc799b51090 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -127,6 +127,7 @@ 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_create_mf(IMFSample *sample, struct wg_sample **out); +HRESULT wg_sample_create_qz(IMediaSample *sample, struct wg_sample **out); void wg_sample_release(struct wg_sample *wg_sample);
HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample, diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index b701b3f6369..715d7c2747b 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -290,7 +290,7 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSample *sample) { struct transform *filter = impl_from_strmbase_filter(pin->pin.filter); - struct wg_sample input_wg_sample = {0}; + struct wg_sample *wg_sample; REFERENCE_TIME start_time; REFERENCE_TIME end_time; HRESULT hr; @@ -311,50 +311,47 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa if (filter->sink.flushing) return S_FALSE;
- input_wg_sample.max_size = IMediaSample_GetSize(sample); - input_wg_sample.size = IMediaSample_GetActualDataLength(sample); - - hr = IMediaSample_GetPointer(sample, &input_wg_sample.data); + hr = wg_sample_create_qz(sample, &wg_sample); if (FAILED(hr)) return hr;
hr = IMediaSample_GetTime(sample, &start_time, &end_time); if (SUCCEEDED(hr)) { - input_wg_sample.pts = start_time; - input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS; + wg_sample->pts = start_time; + wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS; } if (hr == S_OK) { - input_wg_sample.duration = end_time - start_time; - input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION; + wg_sample->duration = end_time - start_time; + wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION; }
- hr = wg_transform_push_data(filter->transform, &input_wg_sample); + hr = wg_transform_push_data(filter->transform, wg_sample); + wg_sample_release(wg_sample); + if (FAILED(hr)) return hr;
for (;;) { - struct wg_sample output_wg_sample = {0}; IMediaSample *output_sample;
hr = IMemAllocator_GetBuffer(filter->source.pAllocator, &output_sample, NULL, NULL, 0); if (FAILED(hr)) return hr;
- output_wg_sample.max_size = IMediaSample_GetSize(output_sample); - - hr = IMediaSample_GetPointer(output_sample, &output_wg_sample.data); + hr = wg_sample_create_qz(output_sample, &wg_sample); if (FAILED(hr)) { IMediaSample_Release(output_sample); return hr; }
- hr = wg_transform_read_data(filter->transform, &output_wg_sample, NULL); + hr = wg_transform_read_data(filter->transform, wg_sample, NULL); if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { + wg_sample_release(wg_sample); IMediaSample_Release(output_sample); break; } @@ -362,23 +359,25 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa { if (hr == MF_E_TRANSFORM_STREAM_CHANGE) FIXME("Unexpected stream format change!\n"); + wg_sample_release(wg_sample); IMediaSample_Release(output_sample); return hr; }
- hr = IMediaSample_SetActualDataLength(output_sample, output_wg_sample.size); + hr = IMediaSample_SetActualDataLength(output_sample, wg_sample->size); if (FAILED(hr)) { + wg_sample_release(wg_sample); IMediaSample_Release(output_sample); return hr; }
- if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_PTS) + if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS) { - start_time = output_wg_sample.pts; - if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_DURATION) + start_time = wg_sample->pts; + if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION) { - end_time = start_time + output_wg_sample.duration; + end_time = start_time + wg_sample->duration; IMediaSample_SetTime(output_sample, &start_time, &end_time); } else @@ -386,6 +385,7 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa IMediaSample_SetTime(output_sample, &start_time, NULL); } } + wg_sample_release(wg_sample);
hr = IMemInputPin_Receive(filter->source.pMemInputPin, output_sample); if (FAILED(hr)) diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 017ec706f50..40af112db39 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -25,6 +25,7 @@ #include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat); +WINE_DECLARE_DEBUG_CHANNEL(quartz);
struct wg_sample_queue { @@ -40,6 +41,7 @@ struct sample enum wg_sample_type { WG_SAMPLE_TYPE_MF = 1, + WG_SAMPLE_TYPE_QZ = 2, } type;
union @@ -49,6 +51,10 @@ struct sample IMFSample *sample; IMFMediaBuffer *buffer; } mf; + struct + { + IMediaSample *sample; + } qz; } u; };
@@ -83,6 +89,32 @@ fail: return hr; }
+HRESULT wg_sample_create_qz(IMediaSample *qz_sample, struct wg_sample **out) +{ + DWORD current_length, max_length; + struct sample *sample; + BYTE *buffer; + HRESULT hr; + + if (FAILED(hr = IMediaSample_GetPointer(qz_sample, &buffer))) + return hr; + current_length = IMediaSample_GetActualDataLength(qz_sample); + max_length = IMediaSample_GetSize(qz_sample); + + if (!(sample = calloc(1, sizeof(*sample)))) + return E_OUTOFMEMORY; + + IMediaSample_AddRef((sample->u.qz.sample = qz_sample)); + sample->wg_sample.data = buffer; + sample->wg_sample.size = current_length; + sample->wg_sample.max_size = max_length; + sample->type = WG_SAMPLE_TYPE_QZ; + + TRACE_(quartz)("Created wg_sample %p for sample %p.\n", &sample->wg_sample, qz_sample); + *out = &sample->wg_sample; + return S_OK; +} + void wg_sample_release(struct wg_sample *wg_sample) { struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); @@ -103,6 +135,12 @@ void wg_sample_release(struct wg_sample *wg_sample) IMFSample_Release(sample->u.mf.sample); break;
+ case WG_SAMPLE_TYPE_QZ: + TRACE_(quartz)("wg_sample %p\n", wg_sample); + + IMediaSample_Release(sample->u.qz.sample); + break; + default: FIXME("Unknown wg_sample %p, type %u\n", wg_sample, sample->type); break;
On 6/10/22 02:53, Rémi Bernon wrote:
enum wg_sample_type { WG_SAMPLE_TYPE_MF = 1,
} type;WG_SAMPLE_TYPE_QZ = 2,
Obvious bikeshedding, but hopefully not controversial—would you please replace this with "quartz", here and elsewhere?
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/quartz_transform.c | 19 ++++------------ dlls/winegstreamer/wg_sample.c | 32 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index cc799b51090..10d0497ba3e 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -132,6 +132,8 @@ void wg_sample_release(struct wg_sample *wg_sample);
HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample, struct wg_sample_queue *queue); +HRESULT wg_transform_push_qz(struct wg_transform *transform, struct wg_sample *sample, + struct wg_sample_queue *queue); HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *sample, struct wg_format *format);
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index 715d7c2747b..0adad9b4c6c 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -315,23 +315,10 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa if (FAILED(hr)) return hr;
- hr = IMediaSample_GetTime(sample, &start_time, &end_time); - if (SUCCEEDED(hr)) - { - wg_sample->pts = start_time; - wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS; - } - if (hr == S_OK) - { - wg_sample->duration = end_time - start_time; - wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION; - } - - hr = wg_transform_push_data(filter->transform, wg_sample); - wg_sample_release(wg_sample); - + hr = wg_transform_push_qz(filter->transform, wg_sample, filter->sample_queue); if (FAILED(hr)) return hr; + wg_sample_queue_flush(filter->sample_queue, false);
for (;;) { @@ -364,6 +351,8 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa return hr; }
+ wg_sample_queue_flush(filter->sample_queue, false); + hr = IMediaSample_SetActualDataLength(output_sample, wg_sample->size); if (FAILED(hr)) { diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 40af112db39..4a0be9460a7 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -246,6 +246,38 @@ HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *w return hr; }
+HRESULT wg_transform_push_qz(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); + REFERENCE_TIME start_pts, end_pts; + HRESULT hr; + + if (sample->type != WG_SAMPLE_TYPE_QZ) + return E_INVALIDARG; + + hr = IMediaSample_GetTime(sample->u.qz.sample, &start_pts, &end_pts); + if (SUCCEEDED(hr)) + { + wg_sample->pts = start_pts; + wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS; + } + if (hr == S_OK) + { + wg_sample->duration = end_pts - start_pts; + wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION; + } + + if (IMediaSample_IsSyncPoint(sample->u.qz.sample) == S_OK) + 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) {
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/quartz_transform.c | 31 +++------------------- dlls/winegstreamer/wg_sample.c | 38 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 10d0497ba3e..6657cb792f9 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -136,6 +136,8 @@ HRESULT wg_transform_push_qz(struct wg_transform *transform, struct wg_sample *s struct wg_sample_queue *queue); HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *sample, struct wg_format *format); +HRESULT wg_transform_read_qz(struct wg_transform *transform, struct wg_sample *sample, + struct wg_format *format);
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj);
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index 0adad9b4c6c..4801de7d3b5 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -291,8 +291,6 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa { struct transform *filter = impl_from_strmbase_filter(pin->pin.filter); struct wg_sample *wg_sample; - REFERENCE_TIME start_time; - REFERENCE_TIME end_time; HRESULT hr;
/* We do not expect pin connection state to change while the filter is @@ -335,10 +333,11 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa return hr; }
- hr = wg_transform_read_data(filter->transform, wg_sample, NULL); + hr = wg_transform_read_qz(filter->transform, wg_sample, NULL); + wg_sample_release(wg_sample); + if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - wg_sample_release(wg_sample); IMediaSample_Release(output_sample); break; } @@ -346,36 +345,12 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa { if (hr == MF_E_TRANSFORM_STREAM_CHANGE) FIXME("Unexpected stream format change!\n"); - wg_sample_release(wg_sample); IMediaSample_Release(output_sample); return hr; }
wg_sample_queue_flush(filter->sample_queue, false);
- hr = IMediaSample_SetActualDataLength(output_sample, wg_sample->size); - if (FAILED(hr)) - { - wg_sample_release(wg_sample); - IMediaSample_Release(output_sample); - return hr; - } - - if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS) - { - start_time = wg_sample->pts; - if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION) - { - end_time = start_time + wg_sample->duration; - IMediaSample_SetTime(output_sample, &start_time, &end_time); - } - else - { - IMediaSample_SetTime(output_sample, &start_time, NULL); - } - } - wg_sample_release(wg_sample); - hr = IMemInputPin_Receive(filter->source.pMemInputPin, output_sample); if (FAILED(hr)) { diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 4a0be9460a7..646d8511821 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -301,3 +301,41 @@ HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *w
return S_OK; } + +HRESULT wg_transform_read_qz(struct wg_transform *transform, struct wg_sample *wg_sample, + struct wg_format *format) +{ + struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); + REFERENCE_TIME start_pts, end_pts; + HRESULT hr; + BOOL value; + + if (sample->type != WG_SAMPLE_TYPE_QZ) + return E_INVALIDARG; + + if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format))) + return hr; + + hr = IMediaSample_SetActualDataLength(sample->u.qz.sample, wg_sample->size); + if (FAILED(hr)) + return hr; + + if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS) + { + start_pts = wg_sample->pts; + if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION) + { + end_pts = start_pts + wg_sample->duration; + IMediaSample_SetTime(sample->u.qz.sample, &start_pts, &end_pts); + } + else + { + IMediaSample_SetTime(sample->u.qz.sample, &start_pts, NULL); + } + } + + value = !!(wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT); + IMediaSample_SetSyncPoint(sample->u.qz.sample, value); + + return S_OK; +}
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 5 ++++- dlls/winegstreamer/main.c | 9 +++++++-- dlls/winegstreamer/unixlib.h | 2 -- dlls/winegstreamer/wg_sample.c | 18 ++++-------------- dlls/winegstreamer/wg_transform.c | 12 +----------- 5 files changed, 16 insertions(+), 30 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 6657cb792f9..5f7a34780fc 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -69,6 +69,8 @@ struct wg_sample_queue; HRESULT wg_sample_queue_create(struct wg_sample_queue **out); void wg_sample_queue_destroy(struct wg_sample_queue *queue); void wg_sample_queue_flush(struct wg_sample_queue *queue, bool all); +void wg_sample_queue_begin_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample); +void wg_sample_queue_end_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample);
struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buffering); void wg_parser_destroy(struct wg_parser *parser); @@ -102,7 +104,8 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, struct wg_transform *wg_transform_create(const struct wg_format *input_format, const struct wg_format *output_format); void wg_transform_destroy(struct wg_transform *transform); -HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample); +HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample, + struct wg_sample_queue *queue); HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample, struct wg_format *format);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 5075b3118cd..c9d1ec0cc20 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -312,7 +312,8 @@ void wg_transform_destroy(struct wg_transform *transform) __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); }
-HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample) +HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample, + struct wg_sample_queue *queue) { struct wg_transform_push_data_params params = { @@ -323,7 +324,11 @@ HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample
TRACE("transform %p, sample %p.\n", transform, sample);
- if ((status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms))) + wg_sample_queue_begin_append(queue, sample); + status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms); + wg_sample_queue_end_append(queue, sample); + + if (status) return HRESULT_FROM_NT(status);
return params.result; diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index ed56fb47908..860a8ab2a52 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -121,8 +121,6 @@ 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_HAS_REFCOUNT = 0x10000, /* sample is queued on the client side and may be wrapped */ };
struct wg_sample diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 646d8511821..bc802008805 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -149,20 +149,19 @@ void wg_sample_release(struct wg_sample *wg_sample) free(sample); }
-static void wg_sample_queue_begin_append(struct wg_sample_queue *queue, struct wg_sample *wg_sample) +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) +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); @@ -221,7 +220,6 @@ HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *w struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); LONGLONG time, duration; UINT32 value; - HRESULT hr;
if (sample->type != WG_SAMPLE_TYPE_MF) return E_INVALIDARG; @@ -239,11 +237,7 @@ HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *w 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); - hr = wg_transform_push_data(transform, wg_sample); - wg_sample_queue_end_append(queue, wg_sample); - - return hr; + return wg_transform_push_data(transform, wg_sample, queue); }
HRESULT wg_transform_push_qz(struct wg_transform *transform, struct wg_sample *wg_sample, @@ -271,11 +265,7 @@ HRESULT wg_transform_push_qz(struct wg_transform *transform, struct wg_sample *w if (IMediaSample_IsSyncPoint(sample->u.qz.sample) == S_OK) 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; + return wg_transform_push_data(transform, wg_sample, queue); }
HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *wg_sample, diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index d40f508250c..b5517f24515 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -542,17 +542,7 @@ NTSTATUS wg_transform_push_data(void *args) return STATUS_SUCCESS; }
- if (!(sample->flags & WG_SAMPLE_FLAG_HAS_REFCOUNT)) - { - if (!(buffer = gst_buffer_new_and_alloc(sample->size))) - { - GST_ERROR("Failed to allocate input buffer"); - return STATUS_NO_MEMORY; - } - gst_buffer_fill(buffer, 0, sample->data, sample->size); - GST_INFO("Copied %u bytes from sample %p to buffer %p", sample->size, sample, buffer); - } - else if (!(buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, sample->data, sample->max_size, + if (!(buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, sample->data, sample->max_size, 0, sample->size, sample, wg_sample_free_notify))) { GST_ERROR("Failed to allocate input buffer");
On 6/10/22 02:53, Rémi Bernon wrote:
@@ -323,7 +324,11 @@ HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample
TRACE("transform %p, sample %p.\n", transform, sample);
- if ((status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms)))
wg_sample_queue_begin_append(queue, sample);
status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms);
wg_sample_queue_end_append(queue, sample);
if (status) return HRESULT_FROM_NT(status);
return params.result;
I don't hate this, but it makes me nervous, since the intent of the helpers was to provide a 1:1 interface to the unix code (modulo types), and this breaks that assumption.