From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/main.c | 13 +++++ dlls/winegstreamer/media_source.c | 81 +++++++++++-------------------- dlls/winegstreamer/unix_private.h | 3 ++ dlls/winegstreamer/unixlib.h | 7 +++ dlls/winegstreamer/wg_parser.c | 30 ++++++++++++ dlls/winegstreamer/wg_transform.c | 4 +- 7 files changed, 84 insertions(+), 55 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 7ae2eb99076..8daa8223584 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -84,6 +84,7 @@ bool wg_parser_stream_get_buffer(struct wg_parser_stream *stream, struct wg_pars bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, void *data, uint32_t offset, uint32_t size); void wg_parser_stream_release_buffer(struct wg_parser_stream *stream); +bool wg_parser_stream_read_data(struct wg_parser_stream *stream, struct wg_sample *sample); void wg_parser_stream_notify_qos(struct wg_parser_stream *stream, bool underflow, double proportion, int64_t diff, uint64_t timestamp);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 5075b3118cd..23153137bd9 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -235,6 +235,19 @@ void wg_parser_stream_release_buffer(struct wg_parser_stream *stream) __wine_unix_call(unix_handle, unix_wg_parser_stream_release_buffer, stream); }
+bool wg_parser_stream_read_data(struct wg_parser_stream *stream, struct wg_sample *sample) +{ + struct wg_parser_stream_read_data_params params = + { + .stream = stream, + .sample = sample, + }; + + TRACE("stream %p, sample %p.\n", stream, sample); + + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_read_data, ¶ms); +} + void wg_parser_stream_notify_qos(struct wg_parser_stream *stream, bool underflow, double proportion, int64_t diff, uint64_t timestamp) { diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index f07b83f413e..1c5518d53d2 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -451,78 +451,53 @@ static void dispatch_end_of_presentation(struct media_source *source) IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MEEndOfPresentation, &GUID_NULL, S_OK, &empty); }
-static void send_buffer(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token) +static HRESULT mf_allocate_sample(UINT32 size, IMFSample **sample) { IMFMediaBuffer *buffer; - IMFSample *sample; HRESULT hr; - BYTE *data;
- if (FAILED(hr = MFCreateSample(&sample))) - { - ERR("Failed to create sample, hr %#lx.\n", hr); - return; - } - - if (FAILED(hr = MFCreateMemoryBuffer(wg_buffer->size, &buffer))) - { - ERR("Failed to create buffer, hr %#lx.\n", hr); - IMFSample_Release(sample); - return; - } + if (FAILED(hr = MFCreateSample(sample))) + return hr;
- if (FAILED(hr = IMFSample_AddBuffer(sample, buffer))) + if (SUCCEEDED(hr = MFCreateMemoryBuffer(size, &buffer))) { - ERR("Failed to add buffer, hr %#lx.\n", hr); - goto out; + hr = IMFSample_AddBuffer(*sample, buffer); + IMFMediaBuffer_Release(buffer); }
- if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, wg_buffer->size))) - { - ERR("Failed to set size, hr %#lx.\n", hr); - goto out; - } + return hr; +}
- if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL))) - { - ERR("Failed to lock buffer, hr %#lx.\n", hr); - goto out; - } +static void send_buffer(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token) +{ + struct wg_sample *wg_sample; + IMFSample *sample; + bool success; + HRESULT hr;
- if (!wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, wg_buffer->size)) + if (FAILED(hr = mf_allocate_sample(wg_buffer->size, &sample))) { - wg_parser_stream_release_buffer(stream->wg_stream); - IMFMediaBuffer_Unlock(buffer); - goto out; + ERR("Failed to create sample, hr %#lx.\n", hr); + return; } - wg_parser_stream_release_buffer(stream->wg_stream); - - if (FAILED(hr = IMFMediaBuffer_Unlock(buffer))) + if (FAILED(hr = wg_sample_wrap_mf(sample, &wg_sample))) { - ERR("Failed to unlock buffer, hr %#lx.\n", hr); - goto out; + ERR("Failed to create sample, hr %#lx.\n", hr); + IMFSample_Release(sample); + return; }
- if (FAILED(hr = IMFSample_SetSampleTime(sample, wg_buffer->pts))) - { - ERR("Failed to set sample time, hr %#lx.\n", hr); - goto out; - } + success = wg_parser_stream_read_data(stream->wg_stream, wg_sample); + wg_sample_unwrap(wg_sample);
- if (FAILED(hr = IMFSample_SetSampleDuration(sample, wg_buffer->duration))) + if (success) { - ERR("Failed to set sample duration, hr %#lx.\n", hr); - goto out; + if (token) + IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token); + IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample, + &GUID_NULL, S_OK, (IUnknown *)sample); }
- if (token) - IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token); - - IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample, - &GUID_NULL, S_OK, (IUnknown *)sample); - -out: - IMFMediaBuffer_Release(buffer); IMFSample_Release(sample); }
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index 7bce8263aaf..c83aabb59e6 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -37,4 +37,7 @@ extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
+extern NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align, + struct wg_sample *sample) DECLSPEC_HIDDEN; + #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index f334a168bd1..79926042f3c 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -217,6 +217,12 @@ struct wg_parser_stream_copy_buffer_params UINT32 size; };
+struct wg_parser_stream_read_data_params +{ + struct wg_parser_stream *stream; + struct wg_sample *sample; +}; + struct wg_parser_stream_notify_qos_params { struct wg_parser_stream *stream; @@ -283,6 +289,7 @@ enum unix_funcs unix_wg_parser_stream_get_buffer, unix_wg_parser_stream_copy_buffer, unix_wg_parser_stream_release_buffer, + unix_wg_parser_stream_read_data, unix_wg_parser_stream_notify_qos,
unix_wg_parser_stream_get_duration, diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 6b1a98c0e7d..c949108f8eb 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -350,6 +350,35 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) return S_OK; }
+static NTSTATUS wg_parser_stream_read_data(void *args) +{ + struct wg_parser_stream_read_data_params *params = args; + struct wg_parser_stream *stream = params->stream; + struct wg_parser *parser = stream->parser; + struct wg_sample *sample = params->sample; + NTSTATUS status; + + pthread_mutex_lock(&parser->mutex); + + if (!stream->buffer) + { + pthread_mutex_unlock(&parser->mutex); + return VFW_E_WRONG_STATE; + } + + status = wg_sample_read_from_buffer(stream->buffer, NULL, 0, sample); + if (!(sample->flags & WG_SAMPLE_FLAG_INCOMPLETE)) + { + gst_buffer_unref(stream->buffer); + stream->buffer = NULL; + pthread_cond_signal(&stream->event_empty_cond); + } + + pthread_mutex_unlock(&parser->mutex); + + return status; +} + static NTSTATUS wg_parser_stream_get_duration(void *args) { struct wg_parser_stream_get_duration_params *params = args; @@ -1617,6 +1646,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_parser_stream_get_buffer), X(wg_parser_stream_copy_buffer), X(wg_parser_stream_release_buffer), + X(wg_parser_stream_read_data), X(wg_parser_stream_notify_qos),
X(wg_parser_stream_get_duration), diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index fb852b4cf3d..7f0d74340db 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -611,7 +611,7 @@ static bool copy_buffer(GstBuffer *buffer, GstCaps *caps, struct wg_sample *samp return true; }
-static NTSTATUS read_transform_output_data(GstBuffer *buffer, GstCaps *caps, gsize plane_align, +NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plane_align, struct wg_sample *sample) { gsize total_size; @@ -725,7 +725,7 @@ NTSTATUS wg_transform_read_data(void *args) return STATUS_SUCCESS; }
- if ((status = read_transform_output_data(output_buffer, output_caps, + if ((status = wg_sample_read_from_buffer(output_buffer, output_caps, transform->output_plane_align, sample))) return status;