Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/Makefile.in | 1 + dlls/winegstreamer/gst_private.h | 32 ++++- dlls/winegstreamer/main.c | 197 ++++++++++++++++++++++++++- dlls/winegstreamer/media_source.c | 44 +++--- dlls/winegstreamer/quartz_parser.c | 72 +++++----- dlls/winegstreamer/unixlib.h | 139 +++++++++++++++---- dlls/winegstreamer/wg_parser.c | 210 ++++++++++++++++++----------- 7 files changed, 528 insertions(+), 167 deletions(-)
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 13e61abee36..e35df3cf3f9 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -1,4 +1,5 @@ MODULE = winegstreamer.dll +UNIXLIB = winegstreamer.so IMPORTS = strmbase strmiids uuid ole32 mfuuid DELAYIMPORTS = mfplat EXTRAINCL = $(GSTREAMER_CFLAGS) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 91c646571cf..ebe0bf6f50d 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -61,7 +61,37 @@ static inline const char *debugstr_time(REFERENCE_TIME time)
#define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
-extern const struct unix_funcs *unix_funcs; +struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buffering) DECLSPEC_HIDDEN; +void wg_parser_destroy(struct wg_parser *parser) DECLSPEC_HIDDEN; + +HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size) DECLSPEC_HIDDEN; +void wg_parser_disconnect(struct wg_parser *parser) DECLSPEC_HIDDEN; + +void wg_parser_begin_flush(struct wg_parser *parser) DECLSPEC_HIDDEN; +void wg_parser_end_flush(struct wg_parser *parser) DECLSPEC_HIDDEN; + +bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size) DECLSPEC_HIDDEN; +void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size) DECLSPEC_HIDDEN; + +uint32_t wg_parser_get_stream_count(struct wg_parser *parser) DECLSPEC_HIDDEN; +struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index) DECLSPEC_HIDDEN; + +void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format) DECLSPEC_HIDDEN; +void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format) DECLSPEC_HIDDEN; +void wg_parser_stream_disable(struct wg_parser_stream *stream) DECLSPEC_HIDDEN; + +bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event) DECLSPEC_HIDDEN; +bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, + void *data, uint32_t offset, uint32_t size) DECLSPEC_HIDDEN; +void wg_parser_stream_release_buffer(struct wg_parser_stream *stream) DECLSPEC_HIDDEN; +void wg_parser_stream_notify_qos(struct wg_parser_stream *stream, + bool underflow, double proportion, int64_t diff, uint64_t timestamp) DECLSPEC_HIDDEN; + +/* Returns the duration in 100-nanosecond units. */ +uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream) DECLSPEC_HIDDEN; +/* start_pos and stop_pos are in 100-nanosecond units. */ +void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, + uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags) DECLSPEC_HIDDEN;
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 6742724948e..c799aa06d1b 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -27,16 +27,209 @@ #include "initguid.h" #include "gst_guids.h"
+static unixlib_handle_t unix_handle; + WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-const struct unix_funcs *unix_funcs = NULL; +struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buffering) +{ + struct wg_parser_create_params params = + { + .type = type, + .unlimited_buffering = unlimited_buffering, + }; + + if (__wine_unix_call(unix_handle, unix_wg_parser_create, ¶ms)) + return NULL; + return params.parser; +} + +void wg_parser_destroy(struct wg_parser *parser) +{ + __wine_unix_call(unix_handle, unix_wg_parser_destroy, parser); +} + +HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size) +{ + struct wg_parser_connect_params params = + { + .parser = parser, + .file_size = file_size, + }; + + return __wine_unix_call(unix_handle, unix_wg_parser_connect, ¶ms); +} + +void wg_parser_disconnect(struct wg_parser *parser) +{ + __wine_unix_call(unix_handle, unix_wg_parser_disconnect, parser); +} + +void wg_parser_begin_flush(struct wg_parser *parser) +{ + __wine_unix_call(unix_handle, unix_wg_parser_begin_flush, parser); +} + +void wg_parser_end_flush(struct wg_parser *parser) +{ + __wine_unix_call(unix_handle, unix_wg_parser_end_flush, parser); +} + +bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size) +{ + struct wg_parser_get_next_read_offset_params params = + { + .parser = parser, + }; + + if (__wine_unix_call(unix_handle, unix_wg_parser_get_next_read_offset, ¶ms)) + return false; + *offset = params.offset; + *size = params.size; + return true; +} + +void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size) +{ + struct wg_parser_push_data_params params = + { + .parser = parser, + .data = data, + .size = size, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_push_data, ¶ms); +} + +uint32_t wg_parser_get_stream_count(struct wg_parser *parser) +{ + struct wg_parser_get_stream_count_params params = + { + .parser = parser, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_get_stream_count, ¶ms); + return params.count; +} + +struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index) +{ + struct wg_parser_get_stream_params params = + { + .parser = parser, + .index = index, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_get_stream, ¶ms); + return params.stream; +} + +void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format) +{ + struct wg_parser_stream_get_preferred_format_params params = + { + .stream = stream, + .format = format, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_stream_get_preferred_format, ¶ms); +} + +void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format) +{ + struct wg_parser_stream_enable_params params = + { + .stream = stream, + .format = format, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_stream_enable, ¶ms); +} + +void wg_parser_stream_disable(struct wg_parser_stream *stream) +{ + __wine_unix_call(unix_handle, unix_wg_parser_stream_disable, stream); +} + +bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event) +{ + struct wg_parser_stream_get_event_params params = + { + .stream = stream, + .event = event, + }; + + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, ¶ms); +} + +bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, + void *data, uint32_t offset, uint32_t size) +{ + struct wg_parser_stream_copy_buffer_params params = + { + .stream = stream, + .data = data, + .offset = offset, + .size = size, + }; + + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_copy_buffer, ¶ms); +} + +void wg_parser_stream_release_buffer(struct wg_parser_stream *stream) +{ + __wine_unix_call(unix_handle, unix_wg_parser_stream_release_buffer, stream); +} + +void wg_parser_stream_notify_qos(struct wg_parser_stream *stream, + bool underflow, double proportion, int64_t diff, uint64_t timestamp) +{ + struct wg_parser_stream_notify_qos_params params = + { + .stream = stream, + .underflow = underflow, + .proportion = proportion, + .diff = diff, + .timestamp = timestamp, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_stream_notify_qos, ¶ms); +} + +uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream) +{ + struct wg_parser_stream_get_duration_params params = + { + .stream = stream, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_stream_get_duration, ¶ms); + return params.duration; +} + +void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, + uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags) +{ + struct wg_parser_stream_seek_params params = + { + .stream = stream, + .rate = rate, + .start_pos = start_pos, + .stop_pos = stop_pos, + .start_flags = start_flags, + .stop_flags = stop_flags, + }; + + __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, ¶ms); +}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(instance); - __wine_init_unix_lib(instance, reason, NULL, &unix_funcs); + NtQueryVirtualMemory(GetCurrentProcess(), instance, MemoryWineUnixFuncs, + &unix_handle, sizeof(unix_handle), NULL); } return TRUE; } diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 18bffca1362..da898f20f66 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -357,7 +357,7 @@ static void start_pipeline(struct media_source *source, struct source_async_comm IMFMediaTypeHandler_GetCurrentMediaType(mth, ¤t_mt);
mf_media_type_to_wg_format(current_mt, &format); - unix_funcs->wg_parser_stream_enable(stream->wg_stream, &format); + wg_parser_stream_enable(stream->wg_stream, &format);
IMFMediaType_Release(current_mt); IMFMediaTypeHandler_Release(mth); @@ -385,9 +385,9 @@ static void start_pipeline(struct media_source *source, struct source_async_comm source->state = SOURCE_RUNNING;
if (position->vt == VT_I8) - unix_funcs->wg_parser_stream_seek(source->streams[0]->wg_stream, 1.0, - position->hVal.QuadPart, 0, AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning); - unix_funcs->wg_parser_end_flush(source->wg_parser); + wg_parser_stream_seek(source->streams[0]->wg_stream, 1.0, position->hVal.QuadPart, 0, + AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning); + wg_parser_end_flush(source->wg_parser);
for (i = 0; i < source->stream_count; i++) flush_token_queue(source->streams[i], position->vt == VT_EMPTY); @@ -415,7 +415,7 @@ static void stop_pipeline(struct media_source *source) { unsigned int i;
- unix_funcs->wg_parser_begin_flush(source->wg_parser); + wg_parser_begin_flush(source->wg_parser);
for (i = 0; i < source->stream_count; i++) { @@ -423,7 +423,7 @@ static void stop_pipeline(struct media_source *source) if (stream->state != STREAM_INACTIVE) { IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamStopped, &GUID_NULL, S_OK, NULL); - unix_funcs->wg_parser_stream_disable(stream->wg_stream); + wg_parser_stream_disable(stream->wg_stream); } }
@@ -490,13 +490,13 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even goto out; }
- if (!unix_funcs->wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, event->u.buffer.size)) + if (!wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, event->u.buffer.size)) { - unix_funcs->wg_parser_stream_release_buffer(stream->wg_stream); + wg_parser_stream_release_buffer(stream->wg_stream); IMFMediaBuffer_Unlock(buffer); goto out; } - unix_funcs->wg_parser_stream_release_buffer(stream->wg_stream); + wg_parser_stream_release_buffer(stream->wg_stream);
if (FAILED(hr = IMFMediaBuffer_Unlock(buffer))) { @@ -536,7 +536,7 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token)
for (;;) { - if (!unix_funcs->wg_parser_stream_get_event(stream->wg_stream, &event)) + if (!wg_parser_stream_get_event(stream->wg_stream, &event)) return;
TRACE("Got event of type %#x.\n", event.type); @@ -628,7 +628,7 @@ static DWORD CALLBACK read_thread(void *arg) uint32_t size; HRESULT hr;
- if (!unix_funcs->wg_parser_get_next_read_offset(source->wg_parser, &offset, &size)) + if (!wg_parser_get_next_read_offset(source->wg_parser, &offset, &size)) continue;
if (offset >= file_size) @@ -650,7 +650,7 @@ static DWORD CALLBACK read_thread(void *arg) ERR("Failed to read %u bytes at offset %I64u, hr %#x.\n", size, offset, hr); else if (ret_size != size) ERR("Unexpected short read: requested %u bytes, got %u.\n", size, ret_size); - unix_funcs->wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size); + wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size); }
free(data); @@ -867,7 +867,7 @@ static HRESULT media_stream_init_desc(struct media_stream *stream) unsigned int i; HRESULT hr;
- unix_funcs->wg_parser_stream_get_preferred_format(stream->wg_stream, &format); + wg_parser_stream_get_preferred_format(stream->wg_stream, &format);
if (format.major_type == WG_MAJOR_TYPE_VIDEO) { @@ -1327,7 +1327,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
source->state = SOURCE_SHUTDOWN;
- unix_funcs->wg_parser_disconnect(source->wg_parser); + wg_parser_disconnect(source->wg_parser);
source->read_thread_shutdown = true; WaitForSingleObject(source->read_thread, INFINITE); @@ -1350,7 +1350,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) IMFMediaStream_Release(&stream->IMFMediaStream_iface); }
- unix_funcs->wg_parser_destroy(source->wg_parser); + wg_parser_destroy(source->wg_parser);
free(source->streams);
@@ -1427,7 +1427,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ * never deselects it). Remove buffering limits from decodebin in order to * account for this. Note that this does leak memory, but the same memory * leak occurs with native. */ - if (!(parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN, true))) + if (!(parser = wg_parser_create(WG_PARSER_DECODEBIN, true))) { hr = E_OUTOFMEMORY; goto fail; @@ -1438,10 +1438,10 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
object->state = SOURCE_OPENING;
- if (FAILED(hr = unix_funcs->wg_parser_connect(parser, file_size))) + if (FAILED(hr = wg_parser_connect(parser, file_size))) goto fail;
- stream_count = unix_funcs->wg_parser_get_stream_count(parser); + stream_count = wg_parser_get_stream_count(parser);
if (!(object->streams = calloc(stream_count, sizeof(*object->streams)))) { @@ -1451,7 +1451,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for (i = 0; i < stream_count; ++i) { - if (FAILED(hr = new_media_stream(object, unix_funcs->wg_parser_get_stream(parser, i), i, &object->streams[i]))) + if (FAILED(hr = new_media_stream(object, wg_parser_get_stream(parser, i), i, &object->streams[i]))) goto fail;
if (FAILED(hr = media_stream_init_desc(object->streams[i]))) @@ -1487,7 +1487,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for (i = 0; i < object->stream_count; i++) total_pres_time = max(total_pres_time, - unix_funcs->wg_parser_stream_get_duration(object->streams[i]->wg_stream)); + wg_parser_stream_get_duration(object->streams[i]->wg_stream));
if (object->stream_count) IMFPresentationDescriptor_SetUINT64(object->pres_desc, &MF_PD_DURATION, total_pres_time); @@ -1518,7 +1518,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ } free(object->streams); if (stream_count != UINT_MAX) - unix_funcs->wg_parser_disconnect(object->wg_parser); + wg_parser_disconnect(object->wg_parser); if (object->read_thread) { object->read_thread_shutdown = true; @@ -1526,7 +1526,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ CloseHandle(object->read_thread); } if (object->wg_parser) - unix_funcs->wg_parser_destroy(object->wg_parser); + wg_parser_destroy(object->wg_parser); if (object->async_commands_queue) MFUnlockWorkQueue(object->async_commands_queue); if (object->event_queue) diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 5dd232ea0da..6ae1a99a14a 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -623,7 +623,7 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample,
IMediaSample_GetPointer(sample, &ptr);
- if (!unix_funcs->wg_parser_stream_copy_buffer(pin->wg_stream, ptr, offset, size)) + if (!wg_parser_stream_copy_buffer(pin->wg_stream, ptr, offset, size)) { /* The GStreamer pin has been flushed. */ return S_OK; @@ -732,7 +732,7 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event } }
- unix_funcs->wg_parser_stream_release_buffer(pin->wg_stream); + wg_parser_stream_release_buffer(pin->wg_stream); }
static DWORD CALLBACK stream_thread(void *arg) @@ -748,7 +748,7 @@ static DWORD CALLBACK stream_thread(void *arg)
EnterCriticalSection(&pin->flushing_cs);
- if (!unix_funcs->wg_parser_stream_get_event(pin->wg_stream, &event)) + if (!wg_parser_stream_get_event(pin->wg_stream, &event)) { LeaveCriticalSection(&pin->flushing_cs); continue; @@ -799,7 +799,7 @@ static DWORD CALLBACK read_thread(void *arg) uint32_t size; HRESULT hr;
- if (!unix_funcs->wg_parser_get_next_read_offset(filter->wg_parser, &offset, &size)) + if (!wg_parser_get_next_read_offset(filter->wg_parser, &offset, &size)) continue;
if (offset >= file_size) @@ -817,7 +817,7 @@ static DWORD CALLBACK read_thread(void *arg) if (FAILED(hr)) ERR("Failed to read %u bytes at offset %I64u, hr %#x.\n", size, offset, hr);
- unix_funcs->wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size); + wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size); }
free(data); @@ -869,7 +869,7 @@ static void parser_destroy(struct strmbase_filter *iface) IAsyncReader_Release(filter->reader); filter->reader = NULL;
- unix_funcs->wg_parser_destroy(filter->wg_parser); + wg_parser_destroy(filter->wg_parser);
strmbase_sink_cleanup(&filter->sink); strmbase_filter_cleanup(&filter->filter); @@ -887,7 +887,7 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface) return S_OK;
filter->streaming = true; - unix_funcs->wg_parser_end_flush(filter->wg_parser); + wg_parser_end_flush(filter->wg_parser);
/* DirectShow retains the old seek positions, but resets to them every time * it transitions from stopped -> paused. */ @@ -895,7 +895,7 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface) seeking = &filter->sources[0]->seek; if (seeking->llStop) stop_flags = AM_SEEKING_AbsolutePositioning; - unix_funcs->wg_parser_stream_seek(filter->sources[0]->wg_stream, seeking->dRate, + wg_parser_stream_seek(filter->sources[0]->wg_stream, seeking->dRate, seeking->llCurrent, seeking->llStop, AM_SEEKING_AbsolutePositioning, stop_flags);
for (i = 0; i < filter->source_count; ++i) @@ -923,7 +923,7 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface) return S_OK;
filter->streaming = false; - unix_funcs->wg_parser_begin_flush(filter->wg_parser); + wg_parser_begin_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i) { @@ -978,7 +978,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons filter->sink_connected = true; filter->read_thread = CreateThread(NULL, 0, read_thread, filter, 0, NULL);
- if (FAILED(hr = unix_funcs->wg_parser_connect(filter->wg_parser, file_size))) + if (FAILED(hr = wg_parser_connect(filter->wg_parser, file_size))) goto err;
if (!filter->init_gst(filter)) @@ -991,7 +991,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons { struct parser_source *pin = filter->sources[i];
- pin->seek.llDuration = pin->seek.llStop = unix_funcs->wg_parser_stream_get_duration(pin->wg_stream); + pin->seek.llDuration = pin->seek.llStop = wg_parser_stream_get_duration(pin->wg_stream); pin->seek.llCurrent = 0; }
@@ -1026,11 +1026,11 @@ static BOOL decodebin_parser_filter_init_gst(struct parser *filter) unsigned int i, stream_count; WCHAR source_name[20];
- stream_count = unix_funcs->wg_parser_get_stream_count(parser); + stream_count = wg_parser_get_stream_count(parser); for (i = 0; i < stream_count; ++i) { swprintf(source_name, ARRAY_SIZE(source_name), L"Stream %02u", i); - if (!create_pin(filter, unix_funcs->wg_parser_get_stream(parser, i), source_name)) + if (!create_pin(filter, wg_parser_get_stream(parser, i), source_name)) return FALSE; }
@@ -1069,7 +1069,7 @@ static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin, WG_VIDEO_FORMAT_RGB15, };
- unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format);
memset(mt, 0, sizeof(AM_MEDIA_TYPE));
@@ -1115,7 +1115,7 @@ HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN, false))) + if (!(object->wg_parser = wg_parser_create(WG_PARSER_DECODEBIN, false))) { free(object); return E_OUTOFMEMORY; @@ -1205,7 +1205,7 @@ static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) { struct parser_source *pin = impl_from_IMediaSeeking(iface);
- unix_funcs->wg_parser_stream_seek(pin->wg_stream, pin->seek.dRate, 0, 0, + wg_parser_stream_seek(pin->wg_stream, pin->seek.dRate, 0, 0, AM_SEEKING_NoPositioning, AM_SEEKING_NoPositioning); return S_OK; } @@ -1247,7 +1247,7 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (!(current_flags & AM_SEEKING_NoFlush)) { - unix_funcs->wg_parser_begin_flush(filter->wg_parser); + wg_parser_begin_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i) { @@ -1269,12 +1269,12 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
SourceSeekingImpl_SetPositions(iface, current, current_flags, stop, stop_flags);
- unix_funcs->wg_parser_stream_seek(pin->wg_stream, pin->seek.dRate, + wg_parser_stream_seek(pin->wg_stream, pin->seek.dRate, pin->seek.llCurrent, pin->seek.llStop, current_flags, stop_flags);
if (!(current_flags & AM_SEEKING_NoFlush)) { - unix_funcs->wg_parser_end_flush(filter->wg_parser); + wg_parser_end_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i) { @@ -1383,7 +1383,7 @@ static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFil /* GST_QOS_TYPE_OVERFLOW is also used for buffers that arrive on time, but * DirectShow filters might use Famine, so check that there actually is an * underrun. */ - unix_funcs->wg_parser_stream_notify_qos(pin->wg_stream, q.Type == Famine && q.Proportion < 1000, + wg_parser_stream_notify_qos(pin->wg_stream, q.Type == Famine && q.Proportion < 1000, 1000.0 / q.Proportion, diff, timestamp);
return S_OK; @@ -1463,7 +1463,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
ret = amt_to_wg_format(&pin->pin.pin.mt, &format); assert(ret); - unix_funcs->wg_parser_stream_enable(pin->wg_stream, &format); + wg_parser_stream_enable(pin->wg_stream, &format);
/* We do need to drop any buffers that might have been sent with the old * caps, but this will be handled in parser_init_stream(). */ @@ -1478,7 +1478,7 @@ static void source_disconnect(struct strmbase_source *iface) { struct parser_source *pin = impl_source_from_IPin(&iface->pin.IPin_iface);
- unix_funcs->wg_parser_stream_disable(pin->wg_stream); + wg_parser_stream_disable(pin->wg_stream); }
static void free_source_pin(struct parser_source *pin) @@ -1544,7 +1544,7 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) if (!This->sink_connected) return S_OK;
- unix_funcs->wg_parser_disconnect(This->wg_parser); + wg_parser_disconnect(This->wg_parser);
/* read_thread() needs to stay alive to service any read requests GStreamer * sends, so we can only shut it down after GStreamer stops. */ @@ -1597,7 +1597,7 @@ static BOOL wave_parser_filter_init_gst(struct parser *filter) { struct wg_parser *parser = filter->wg_parser;
- if (!create_pin(filter, unix_funcs->wg_parser_get_stream(parser, 0), L"output")) + if (!create_pin(filter, wg_parser_get_stream(parser, 0), L"output")) return FALSE;
return TRUE; @@ -1609,7 +1609,7 @@ static HRESULT wave_parser_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE pad_mt; HRESULT hr;
- unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(&pad_mt, &format)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; @@ -1624,7 +1624,7 @@ static HRESULT wave_parser_source_get_media_type(struct parser_source *pin,
if (index > 0) return VFW_S_NO_MORE_ITEMS; - unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(mt, &format)) return E_OUTOFMEMORY; return S_OK; @@ -1640,7 +1640,7 @@ HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_WAVPARSE, false))) + if (!(object->wg_parser = wg_parser_create(WG_PARSER_WAVPARSE, false))) { free(object); return E_OUTOFMEMORY; @@ -1678,11 +1678,11 @@ static BOOL avi_splitter_filter_init_gst(struct parser *filter) uint32_t i, stream_count; WCHAR source_name[20];
- stream_count = unix_funcs->wg_parser_get_stream_count(parser); + stream_count = wg_parser_get_stream_count(parser); for (i = 0; i < stream_count; ++i) { swprintf(source_name, ARRAY_SIZE(source_name), L"Stream %02u", i); - if (!create_pin(filter, unix_funcs->wg_parser_get_stream(parser, i), source_name)) + if (!create_pin(filter, wg_parser_get_stream(parser, i), source_name)) return FALSE; }
@@ -1695,7 +1695,7 @@ static HRESULT avi_splitter_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE pad_mt; HRESULT hr;
- unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(&pad_mt, &format)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; @@ -1710,7 +1710,7 @@ static HRESULT avi_splitter_source_get_media_type(struct parser_source *pin,
if (index > 0) return VFW_S_NO_MORE_ITEMS; - unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(mt, &format)) return E_OUTOFMEMORY; return S_OK; @@ -1726,7 +1726,7 @@ HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_AVIDEMUX, false))) + if (!(object->wg_parser = wg_parser_create(WG_PARSER_AVIDEMUX, false))) { free(object); return E_OUTOFMEMORY; @@ -1767,7 +1767,7 @@ static BOOL mpeg_splitter_filter_init_gst(struct parser *filter) { struct wg_parser *parser = filter->wg_parser;
- if (!create_pin(filter, unix_funcs->wg_parser_get_stream(parser, 0), L"Audio")) + if (!create_pin(filter, wg_parser_get_stream(parser, 0), L"Audio")) return FALSE;
return TRUE; @@ -1779,7 +1779,7 @@ static HRESULT mpeg_splitter_source_query_accept(struct parser_source *pin, cons AM_MEDIA_TYPE pad_mt; HRESULT hr;
- unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(&pad_mt, &format)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; @@ -1794,7 +1794,7 @@ static HRESULT mpeg_splitter_source_get_media_type(struct parser_source *pin,
if (index > 0) return VFW_S_NO_MORE_ITEMS; - unix_funcs->wg_parser_stream_get_preferred_format(pin->wg_stream, &format); + wg_parser_stream_get_preferred_format(pin->wg_stream, &format); if (!amt_from_wg_format(mt, &format)) return E_OUTOFMEMORY; return S_OK; @@ -1833,7 +1833,7 @@ HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_MPEGAUDIOPARSE, false))) + if (!(object->wg_parser = wg_parser_create(WG_PARSER_MPEGAUDIOPARSE, false))) { free(object); return E_OUTOFMEMORY; diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index dade020916a..90101893541 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -24,9 +24,12 @@ #include <stdbool.h> #include <stdint.h> #include "windef.h" +#include "winternl.h" #include "wtypes.h" #include "mmreg.h"
+#include "wine/unixlib.h" + struct wg_format { enum wg_major_type @@ -125,41 +128,123 @@ enum wg_parser_type WG_PARSER_WAVPARSE, };
-struct unix_funcs +struct wg_parser_create_params { - struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type, bool unlimited_buffering); - void (CDECL *wg_parser_destroy)(struct wg_parser *parser); + struct wg_parser *parser; + enum wg_parser_type type; + bool unlimited_buffering; +};
- HRESULT (CDECL *wg_parser_connect)(struct wg_parser *parser, uint64_t file_size); - void (CDECL *wg_parser_disconnect)(struct wg_parser *parser); +struct wg_parser_connect_params +{ + struct wg_parser *parser; + UINT64 file_size; +};
- void (CDECL *wg_parser_begin_flush)(struct wg_parser *parser); - void (CDECL *wg_parser_end_flush)(struct wg_parser *parser); +struct wg_parser_get_next_read_offset_params +{ + struct wg_parser *parser; + UINT32 size; + UINT64 offset; +};
- bool (CDECL *wg_parser_get_next_read_offset)(struct wg_parser *parser, - uint64_t *offset, uint32_t *size); - void (CDECL *wg_parser_push_data)(struct wg_parser *parser, - const void *data, uint32_t size); +struct wg_parser_push_data_params +{ + struct wg_parser *parser; + const void *data; + UINT32 size; +};
- uint32_t (CDECL *wg_parser_get_stream_count)(struct wg_parser *parser); - struct wg_parser_stream *(CDECL *wg_parser_get_stream)(struct wg_parser *parser, uint32_t index); +struct wg_parser_get_stream_count_params +{ + struct wg_parser *parser; + UINT32 count; +};
- void (CDECL *wg_parser_stream_get_preferred_format)(struct wg_parser_stream *stream, struct wg_format *format); - void (CDECL *wg_parser_stream_enable)(struct wg_parser_stream *stream, const struct wg_format *format); - void (CDECL *wg_parser_stream_disable)(struct wg_parser_stream *stream); +struct wg_parser_get_stream_params +{ + struct wg_parser *parser; + UINT32 index; + struct wg_parser_stream *stream; +};
- bool (CDECL *wg_parser_stream_get_event)(struct wg_parser_stream *stream, struct wg_parser_event *event); - bool (CDECL *wg_parser_stream_copy_buffer)(struct wg_parser_stream *stream, - void *data, uint32_t offset, uint32_t size); - void (CDECL *wg_parser_stream_release_buffer)(struct wg_parser_stream *stream); - void (CDECL *wg_parser_stream_notify_qos)(struct wg_parser_stream *stream, - bool underflow, double proportion, int64_t diff, uint64_t timestamp); +struct wg_parser_stream_get_preferred_format_params +{ + struct wg_parser_stream *stream; + struct wg_format *format; +};
- /* Returns the duration in 100-nanosecond units. */ - uint64_t (CDECL *wg_parser_stream_get_duration)(struct wg_parser_stream *stream); - /* start_pos and stop_pos are in 100-nanosecond units. */ - void (CDECL *wg_parser_stream_seek)(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); +struct wg_parser_stream_enable_params +{ + struct wg_parser_stream *stream; + const struct wg_format *format; +}; + +struct wg_parser_stream_get_event_params +{ + struct wg_parser_stream *stream; + struct wg_parser_event *event; +}; + +struct wg_parser_stream_copy_buffer_params +{ + struct wg_parser_stream *stream; + void *data; + UINT32 offset; + UINT32 size; +}; + +struct wg_parser_stream_notify_qos_params +{ + struct wg_parser_stream *stream; + bool underflow; + DOUBLE proportion; + INT64 diff; + UINT64 timestamp; +}; + +struct wg_parser_stream_get_duration_params +{ + struct wg_parser_stream *stream; + UINT64 duration; +}; + +struct wg_parser_stream_seek_params +{ + struct wg_parser_stream *stream; + DOUBLE rate; + UINT64 start_pos, stop_pos; + DWORD start_flags, stop_flags; +}; + +enum unix_funcs +{ + unix_wg_parser_create, + unix_wg_parser_destroy, + + unix_wg_parser_connect, + unix_wg_parser_disconnect, + + unix_wg_parser_begin_flush, + unix_wg_parser_end_flush, + + unix_wg_parser_get_next_read_offset, + unix_wg_parser_push_data, + + unix_wg_parser_get_stream_count, + unix_wg_parser_get_stream, + + unix_wg_parser_stream_get_preferred_format, + unix_wg_parser_stream_enable, + unix_wg_parser_stream_disable, + + unix_wg_parser_stream_get_event, + unix_wg_parser_stream_copy_buffer, + unix_wg_parser_stream_release_buffer, + unix_wg_parser_stream_notify_qos, + + unix_wg_parser_stream_get_duration, + unix_wg_parser_stream_seek, };
#endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 694f8b57ed1..72dfab8f3d6 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -34,8 +34,6 @@ #include <gst/video/video.h> #include <gst/audio/audio.h>
-#include "ntstatus.h" -#define WIN32_NO_STATUS #include "winternl.h" #include "dshow.h"
@@ -503,18 +501,25 @@ static bool wg_format_compare(const struct wg_format *a, const struct wg_format return false; }
-static uint32_t CDECL wg_parser_get_stream_count(struct wg_parser *parser) +static NTSTATUS wg_parser_get_stream_count(void *args) { - return parser->stream_count; + struct wg_parser_get_stream_count_params *params = args; + + params->count = params->parser->stream_count; + return S_OK; }
-static struct wg_parser_stream * CDECL wg_parser_get_stream(struct wg_parser *parser, uint32_t index) +static NTSTATUS wg_parser_get_stream(void *args) { - return parser->streams[index]; + struct wg_parser_get_stream_params *params = args; + + params->stream = params->parser->streams[params->index]; + return S_OK; }
-static void CDECL wg_parser_begin_flush(struct wg_parser *parser) +static NTSTATUS wg_parser_begin_flush(void *args) { + struct wg_parser *parser = args; unsigned int i;
pthread_mutex_lock(&parser->mutex); @@ -526,18 +531,26 @@ static void CDECL wg_parser_begin_flush(struct wg_parser *parser) if (parser->streams[i]->enabled) pthread_cond_signal(&parser->streams[i]->event_cond); } + + return S_OK; }
-static void CDECL wg_parser_end_flush(struct wg_parser *parser) +static NTSTATUS wg_parser_end_flush(void *args) { + struct wg_parser *parser = args; + pthread_mutex_lock(&parser->mutex); parser->flushing = false; pthread_mutex_unlock(&parser->mutex); + + return S_OK; }
-static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser, - uint64_t *offset, uint32_t *size) +static NTSTATUS wg_parser_get_next_read_offset(void *args) { + struct wg_parser_get_next_read_offset_params *params = args; + struct wg_parser *parser = params->parser; + pthread_mutex_lock(&parser->mutex);
while (parser->sink_connected && !parser->read_request.data) @@ -546,19 +559,23 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser, if (!parser->sink_connected) { pthread_mutex_unlock(&parser->mutex); - return false; + return VFW_E_WRONG_STATE; }
- *offset = parser->read_request.offset; - *size = parser->read_request.size; + params->offset = parser->read_request.offset; + params->size = parser->read_request.size;
pthread_mutex_unlock(&parser->mutex); - return true; + return S_OK; }
-static void CDECL wg_parser_push_data(struct wg_parser *parser, - const void *data, uint32_t size) +static NTSTATUS wg_parser_push_data(void *args) { + const struct wg_parser_push_data_params *params = args; + struct wg_parser *parser = params->parser; + const void *data = params->data; + uint32_t size = params->size; + pthread_mutex_lock(&parser->mutex); parser->read_request.size = size; parser->read_request.done = true; @@ -568,15 +585,24 @@ static void CDECL wg_parser_push_data(struct wg_parser *parser, parser->read_request.data = NULL; pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->read_done_cond); + + return S_OK; }
-static void CDECL wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format) +static NTSTATUS wg_parser_stream_get_preferred_format(void *args) { - *format = stream->preferred_format; + const struct wg_parser_stream_get_preferred_format_params *params = args; + + *params->format = params->stream->preferred_format; + return S_OK; }
-static void CDECL wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format) +static NTSTATUS wg_parser_stream_enable(void *args) { + const struct wg_parser_stream_enable_params *params = args; + struct wg_parser_stream *stream = params->stream; + const struct wg_format *format = params->format; + stream->current_format = *format; stream->enabled = true;
@@ -607,15 +633,21 @@ static void CDECL wg_parser_stream_enable(struct wg_parser_stream *stream, const }
gst_pad_push_event(stream->my_sink, gst_event_new_reconfigure()); + return S_OK; }
-static void CDECL wg_parser_stream_disable(struct wg_parser_stream *stream) +static NTSTATUS wg_parser_stream_disable(void *args) { + struct wg_parser_stream *stream = args; + stream->enabled = false; + return S_OK; }
-static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event) +static NTSTATUS wg_parser_stream_get_event(void *args) { + const struct wg_parser_stream_get_event_params *params = args; + struct wg_parser_stream *stream = params->stream; struct wg_parser *parser = stream->parser;
pthread_mutex_lock(&parser->mutex); @@ -627,10 +659,10 @@ static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, st { pthread_mutex_unlock(&parser->mutex); GST_DEBUG("Filter is flushing.\n"); - return false; + return VFW_E_WRONG_STATE; }
- *event = stream->event; + *params->event = stream->event;
if (stream->event.type != WG_PARSER_EVENT_BUFFER) { @@ -639,33 +671,37 @@ static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, st } pthread_mutex_unlock(&parser->mutex);
- return true; + return S_OK; }
-static bool CDECL wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, - void *data, uint32_t offset, uint32_t size) +static NTSTATUS wg_parser_stream_copy_buffer(void *args) { + const struct wg_parser_stream_copy_buffer_params *params = args; + struct wg_parser_stream *stream = params->stream; struct wg_parser *parser = stream->parser; + uint32_t offset = params->offset; + uint32_t size = params->size;
pthread_mutex_lock(&parser->mutex);
if (!stream->buffer) { pthread_mutex_unlock(&parser->mutex); - return false; + return VFW_E_WRONG_STATE; }
assert(stream->event.type == WG_PARSER_EVENT_BUFFER); assert(offset < stream->map_info.size); assert(offset + size <= stream->map_info.size); - memcpy(data, stream->map_info.data + offset, size); + memcpy(params->data, stream->map_info.data + offset, size);
pthread_mutex_unlock(&parser->mutex); - return true; + return S_OK; }
-static void CDECL wg_parser_stream_release_buffer(struct wg_parser_stream *stream) +static NTSTATUS wg_parser_stream_release_buffer(void *args) { + struct wg_parser_stream *stream = args; struct wg_parser *parser = stream->parser;
pthread_mutex_lock(&parser->mutex); @@ -679,17 +715,24 @@ static void CDECL wg_parser_stream_release_buffer(struct wg_parser_stream *strea
pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&stream->event_empty_cond); + + return S_OK; }
-static uint64_t CDECL wg_parser_stream_get_duration(struct wg_parser_stream *stream) +static NTSTATUS wg_parser_stream_get_duration(void *args) { - return stream->duration; + struct wg_parser_stream_get_duration_params *params = args; + + params->duration = params->stream->duration; + return S_OK; }
-static void CDECL wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags) +static NTSTATUS wg_parser_stream_seek(void *args) { GstSeekType start_type = GST_SEEK_TYPE_SET, stop_type = GST_SEEK_TYPE_SET; + const struct wg_parser_stream_seek_params *params = args; + DWORD start_flags = params->start_flags; + DWORD stop_flags = params->stop_flags; GstSeekFlags flags = 0;
if (start_flags & AM_SEEKING_SeekToKeyFrame) @@ -704,34 +747,39 @@ static void CDECL wg_parser_stream_seek(struct wg_parser_stream *stream, double if ((stop_flags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning) stop_type = GST_SEEK_TYPE_NONE;
- if (!gst_pad_push_event(stream->my_sink, gst_event_new_seek(rate, GST_FORMAT_TIME, - flags, start_type, start_pos * 100, stop_type, stop_pos * 100))) + if (!gst_pad_push_event(params->stream->my_sink, gst_event_new_seek(params->rate, GST_FORMAT_TIME, + flags, start_type, params->start_pos * 100, stop_type, params->stop_pos * 100))) GST_ERROR("Failed to seek.\n"); + + return S_OK; }
-static void CDECL wg_parser_stream_notify_qos(struct wg_parser_stream *stream, - bool underflow, double proportion, int64_t diff, uint64_t timestamp) +static NTSTATUS wg_parser_stream_notify_qos(void *args) { + const struct wg_parser_stream_notify_qos_params *params = args; + struct wg_parser_stream *stream = params->stream; GstClockTime stream_time; GstEvent *event;
/* We return timestamps in stream time, i.e. relative to the start of the * file (or other medium), but gst_event_new_qos() expects the timestamp in * running time. */ - stream_time = gst_segment_to_running_time(&stream->segment, GST_FORMAT_TIME, timestamp * 100); + stream_time = gst_segment_to_running_time(&stream->segment, GST_FORMAT_TIME, params->timestamp * 100); if (stream_time == -1) { /* This can happen legitimately if the sample falls outside of the * segment bounds. GStreamer elements shouldn't present the sample in * that case, but DirectShow doesn't care. */ GST_LOG("Ignoring QoS event.\n"); - return; + return S_OK; }
- if (!(event = gst_event_new_qos(underflow ? GST_QOS_TYPE_UNDERFLOW : GST_QOS_TYPE_OVERFLOW, - proportion, diff * 100, stream_time))) + if (!(event = gst_event_new_qos(params->underflow ? GST_QOS_TYPE_UNDERFLOW : GST_QOS_TYPE_OVERFLOW, + params->proportion, params->diff * 100, stream_time))) GST_ERROR("Failed to create QOS event.\n"); gst_pad_push_event(stream->my_sink, event); + + return S_OK; }
static GstAutoplugSelectResult autoplug_select_cb(GstElement *bin, GstPad *pad, @@ -1527,14 +1575,16 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) return ret; }
-static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_size) +static NTSTATUS wg_parser_connect(void *args) { GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("quartz_src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); + const struct wg_parser_connect_params *params = args; + struct wg_parser *parser = params->parser; unsigned int i; int ret;
- parser->file_size = file_size; + parser->file_size = params->file_size; parser->sink_connected = true;
if (!parser->bus) @@ -1684,8 +1734,9 @@ out: return E_FAIL; }
-static void CDECL wg_parser_disconnect(struct wg_parser *parser) +static NTSTATUS wg_parser_disconnect(void *args) { + struct wg_parser *parser = args; unsigned int i;
/* Unblock all of our streams. */ @@ -1718,6 +1769,8 @@ static void CDECL wg_parser_disconnect(struct wg_parser *parser) gst_element_set_bus(parser->container, NULL); gst_object_unref(parser->container); parser->container = NULL; + + return S_OK; }
static BOOL decodebin_parser_init_gst(struct wg_parser *parser) @@ -1878,7 +1931,7 @@ static void init_gstreamer_once(void) gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); }
-static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type, bool unlimited_buffering) +static NTSTATUS wg_parser_create(void *args) { static const init_gst_cb init_funcs[] = { @@ -1889,28 +1942,32 @@ static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type, bool };
static pthread_once_t once = PTHREAD_ONCE_INIT; + struct wg_parser_create_params *params = args; struct wg_parser *parser;
if (pthread_once(&once, init_gstreamer_once)) - return NULL; + return E_FAIL;
if (!(parser = calloc(1, sizeof(*parser)))) - return NULL; + return E_OUTOFMEMORY;
pthread_mutex_init(&parser->mutex, NULL); pthread_cond_init(&parser->init_cond, NULL); pthread_cond_init(&parser->read_cond, NULL); pthread_cond_init(&parser->read_done_cond, NULL); parser->flushing = true; - parser->init_gst = init_funcs[type]; - parser->unlimited_buffering = unlimited_buffering; + parser->init_gst = init_funcs[params->type]; + parser->unlimited_buffering = params->unlimited_buffering;
GST_DEBUG("Created winegstreamer parser %p.\n", parser); - return parser; + params->parser = parser; + return S_OK; }
-static void CDECL wg_parser_destroy(struct wg_parser *parser) +static NTSTATUS wg_parser_destroy(void *args) { + struct wg_parser *parser = args; + if (parser->bus) { gst_bus_set_sync_handler(parser->bus, NULL, NULL, NULL); @@ -1923,41 +1980,36 @@ static void CDECL wg_parser_destroy(struct wg_parser *parser) pthread_cond_destroy(&parser->read_done_cond);
free(parser); + return S_OK; }
-static const struct unix_funcs funcs = +const unixlib_entry_t __wine_unix_call_funcs[] = { - wg_parser_create, - wg_parser_destroy, +#define X(name) [unix_ ## name] = name + X(wg_parser_create), + X(wg_parser_destroy),
- wg_parser_connect, - wg_parser_disconnect, + X(wg_parser_connect), + X(wg_parser_disconnect),
- wg_parser_begin_flush, - wg_parser_end_flush, + X(wg_parser_begin_flush), + X(wg_parser_end_flush),
- wg_parser_get_next_read_offset, - wg_parser_push_data, + X(wg_parser_get_next_read_offset), + X(wg_parser_push_data),
- wg_parser_get_stream_count, - wg_parser_get_stream, + X(wg_parser_get_stream_count), + X(wg_parser_get_stream),
- wg_parser_stream_get_preferred_format, - wg_parser_stream_enable, - wg_parser_stream_disable, + X(wg_parser_stream_get_preferred_format), + X(wg_parser_stream_enable), + X(wg_parser_stream_disable),
- wg_parser_stream_get_event, - wg_parser_stream_copy_buffer, - wg_parser_stream_release_buffer, - wg_parser_stream_notify_qos, + X(wg_parser_stream_get_event), + X(wg_parser_stream_copy_buffer), + X(wg_parser_stream_release_buffer), + X(wg_parser_stream_notify_qos),
- wg_parser_stream_get_duration, - wg_parser_stream_seek, + X(wg_parser_stream_get_duration), + X(wg_parser_stream_seek), }; - -NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) -{ - if (reason == DLL_PROCESS_ATTACH) - *(const struct unix_funcs **)ptr_out = &funcs; - return STATUS_SUCCESS; -}