diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 2f37d97378d..2cbba09f9a7 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -80,7 +80,7 @@ void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, stru void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format); void wg_parser_stream_disable(struct wg_parser_stream *stream); -bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event); +bool wg_parser_stream_get_buffer(struct wg_parser_stream *stream, struct wg_parser_buffer *buffer); 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); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index e9e347b0c65..327d144499e 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -172,15 +172,15 @@ 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) +bool wg_parser_stream_get_buffer(struct wg_parser_stream *stream, struct wg_parser_buffer *buffer) { - struct wg_parser_stream_get_event_params params = + struct wg_parser_stream_get_buffer_params params = { .stream = stream, - .event = event, + .buffer = buffer, }; - return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, ¶ms); + return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_buffer, ¶ms); } bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream, diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 92cb27dc5dc..c9f95a8a451 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -450,7 +450,7 @@ 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_event *event, IUnknown *token) +static void send_buffer(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token) { IMFMediaBuffer *buffer; IMFSample *sample; @@ -463,7 +463,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even return; } - if (FAILED(hr = MFCreateMemoryBuffer(event->u.buffer.size, &buffer))) + if (FAILED(hr = MFCreateMemoryBuffer(wg_buffer->size, &buffer))) { ERR("Failed to create buffer, hr %#lx.\n", hr); IMFSample_Release(sample); @@ -476,7 +476,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even goto out; } - if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, event->u.buffer.size))) + if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, wg_buffer->size))) { ERR("Failed to set size, hr %#lx.\n", hr); goto out; @@ -488,7 +488,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even goto out; } - if (!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, wg_buffer->size)) { wg_parser_stream_release_buffer(stream->wg_stream); IMFMediaBuffer_Unlock(buffer); @@ -502,13 +502,13 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even goto out; } - if (FAILED(hr = IMFSample_SetSampleTime(sample, event->u.buffer.pts))) + if (FAILED(hr = IMFSample_SetSampleTime(sample, wg_buffer->pts))) { ERR("Failed to set sample time, hr %#lx.\n", hr); goto out; } - if (FAILED(hr = IMFSample_SetSampleDuration(sample, event->u.buffer.duration))) + if (FAILED(hr = IMFSample_SetSampleDuration(sample, wg_buffer->duration))) { ERR("Failed to set sample duration, hr %#lx.\n", hr); goto out; @@ -528,13 +528,13 @@ out: static void wait_on_sample(struct media_stream *stream, IUnknown *token) { PROPVARIANT empty_var = {.vt = VT_EMPTY}; - struct wg_parser_event event; + struct wg_parser_buffer buffer; TRACE("%p, %p\n", stream, token); - if (wg_parser_stream_get_event(stream->wg_stream, &event)) + if (wg_parser_stream_get_buffer(stream->wg_stream, &buffer)) { - send_buffer(stream, &event, token); + send_buffer(stream, &buffer, token); } else { diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 9b0fa4acb93..d369d4c7f20 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -686,7 +686,7 @@ static uint64_t scale_uint64(uint64_t value, uint32_t numerator, uint32_t denomi /* Fill and send a single IMediaSample. */ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, - const struct wg_parser_event *event, uint32_t offset, uint32_t size, DWORD bytes_per_second) + const struct wg_parser_buffer *buffer, uint32_t offset, uint32_t size, DWORD bytes_per_second) { HRESULT hr; BYTE *ptr = NULL; @@ -707,21 +707,21 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, return S_OK; } - if (event->u.buffer.has_pts) + if (buffer->has_pts) { - REFERENCE_TIME start_pts = event->u.buffer.pts; + REFERENCE_TIME start_pts = buffer->pts; if (offset) start_pts += scale_uint64(offset, 10000000, bytes_per_second); start_pts -= pin->seek.llCurrent; start_pts *= pin->seek.dRate; - if (event->u.buffer.has_duration) + if (buffer->has_duration) { - REFERENCE_TIME end_pts = event->u.buffer.pts + event->u.buffer.duration; + REFERENCE_TIME end_pts = buffer->pts + buffer->duration; - if (offset + size < event->u.buffer.size) - end_pts = event->u.buffer.pts + scale_uint64(offset + size, 10000000, bytes_per_second); + if (offset + size < buffer->size) + end_pts = buffer->pts + scale_uint64(offset + size, 10000000, bytes_per_second); end_pts -= pin->seek.llCurrent; end_pts *= pin->seek.dRate; @@ -740,9 +740,9 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, IMediaSample_SetMediaTime(sample, NULL, NULL); } - IMediaSample_SetDiscontinuity(sample, !offset && event->u.buffer.discontinuity); - IMediaSample_SetPreroll(sample, event->u.buffer.preroll); - IMediaSample_SetSyncPoint(sample, !event->u.buffer.delta); + IMediaSample_SetDiscontinuity(sample, !offset && buffer->discontinuity); + IMediaSample_SetPreroll(sample, buffer->preroll); + IMediaSample_SetSyncPoint(sample, !buffer->delta); if (!pin->pin.pin.peer) return VFW_E_NOT_CONNECTED; @@ -754,7 +754,7 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, /* Send a single GStreamer buffer (splitting it into multiple IMediaSamples if * necessary). */ -static void send_buffer(struct parser_source *pin, const struct wg_parser_event *event) +static void send_buffer(struct parser_source *pin, const struct wg_parser_buffer *buffer) { HRESULT hr; IMediaSample *sample; @@ -774,7 +774,7 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event WAVEFORMATEX *format = (WAVEFORMATEX *)pin->pin.pin.mt.pbFormat; uint32_t offset = 0; - while (offset < event->u.buffer.size) + while (offset < buffer->size) { uint32_t advance; @@ -784,9 +784,9 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event break; } - advance = min(IMediaSample_GetSize(sample), event->u.buffer.size - offset); + advance = min(IMediaSample_GetSize(sample), buffer->size - offset); - hr = send_sample(pin, sample, event, offset, advance, format->nAvgBytesPerSec); + hr = send_sample(pin, sample, buffer, offset, advance, format->nAvgBytesPerSec); IMediaSample_Release(sample); @@ -804,7 +804,7 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event } else { - hr = send_sample(pin, sample, event, 0, event->u.buffer.size, 0); + hr = send_sample(pin, sample, buffer, 0, buffer->size, 0); IMediaSample_Release(sample); } @@ -822,7 +822,7 @@ static DWORD CALLBACK stream_thread(void *arg) while (filter->streaming) { - struct wg_parser_event event; + struct wg_parser_buffer buffer; EnterCriticalSection(&pin->flushing_cs); @@ -833,9 +833,9 @@ static DWORD CALLBACK stream_thread(void *arg) continue; } - if (wg_parser_stream_get_event(pin->wg_stream, &event)) + if (wg_parser_stream_get_buffer(pin->wg_stream, &buffer)) { - send_buffer(pin, &event); + send_buffer(pin, &buffer); } else { @@ -844,8 +844,6 @@ static DWORD CALLBACK stream_thread(void *arg) pin->eos = true; } - TRACE("Got event of type %#x.\n", event.type); - LeaveCriticalSection(&pin->flushing_cs); } diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 9d75e94cb6a..3dfa30b4889 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -103,27 +103,14 @@ struct wg_format } u; }; -enum wg_parser_event_type +struct wg_parser_buffer { - WG_PARSER_EVENT_NONE = 0, - WG_PARSER_EVENT_BUFFER, + /* pts and duration are in 100-nanosecond units. */ + UINT64 pts, duration; + UINT32 size; + bool discontinuity, preroll, delta, has_pts, has_duration; }; - -struct wg_parser_event -{ - enum wg_parser_event_type type; - union - { - struct - { - /* pts and duration are in 100-nanosecond units. */ - ULONGLONG pts, duration; - uint32_t size; - bool discontinuity, preroll, delta, has_pts, has_duration; - } buffer; - } u; -}; -C_ASSERT(sizeof(struct wg_parser_event) == 40); +C_ASSERT(sizeof(struct wg_parser_buffer) == 32); enum wg_parser_type { @@ -185,10 +172,10 @@ struct wg_parser_stream_enable_params const struct wg_format *format; }; -struct wg_parser_stream_get_event_params +struct wg_parser_stream_get_buffer_params { struct wg_parser_stream *stream; - struct wg_parser_event *event; + struct wg_parser_buffer *buffer; }; struct wg_parser_stream_copy_buffer_params @@ -247,7 +234,7 @@ enum unix_funcs unix_wg_parser_stream_enable, unix_wg_parser_stream_disable, - unix_wg_parser_stream_get_event, + unix_wg_parser_stream_get_buffer, unix_wg_parser_stream_copy_buffer, unix_wg_parser_stream_release_buffer, unix_wg_parser_stream_notify_qos, diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index e114a19a26b..f36feead9c6 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -102,7 +102,6 @@ struct wg_parser_stream struct wg_format preferred_format, current_format; pthread_cond_t event_cond, event_empty_cond; - struct wg_parser_event event; GstBuffer *buffer; GstMapInfo map_info; @@ -251,22 +250,37 @@ static NTSTATUS wg_parser_stream_disable(void *args) return S_OK; } -static NTSTATUS wg_parser_stream_get_event(void *args) +static NTSTATUS wg_parser_stream_get_buffer(void *args) { - const struct wg_parser_stream_get_event_params *params = args; + const struct wg_parser_stream_get_buffer_params *params = args; + struct wg_parser_buffer *wg_buffer = params->buffer; struct wg_parser_stream *stream = params->stream; struct wg_parser *parser = stream->parser; + GstBuffer *buffer; pthread_mutex_lock(&parser->mutex); - while (!stream->eos && stream->event.type == WG_PARSER_EVENT_NONE) + while (!stream->eos && !stream->buffer) pthread_cond_wait(&stream->event_cond, &parser->mutex); /* Note that we can both have a buffer and stream->eos, in which case we * must return the buffer. */ - if (stream->event.type != WG_PARSER_EVENT_NONE) + if ((buffer = stream->buffer)) { - *params->event = stream->event; + /* FIXME: Should we use gst_segment_to_stream_time_full()? Under what + * circumstances is the stream time not equal to the buffer PTS? Note + * that this will need modification to wg_parser_stream_notify_qos() as + * well. */ + + if ((wg_buffer->has_pts = GST_BUFFER_PTS_IS_VALID(buffer))) + wg_buffer->pts = GST_BUFFER_PTS(buffer) / 100; + if ((wg_buffer->has_duration = GST_BUFFER_DURATION_IS_VALID(buffer))) + wg_buffer->duration = GST_BUFFER_DURATION(buffer) / 100; + wg_buffer->discontinuity = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); + wg_buffer->preroll = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE); + wg_buffer->delta = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + wg_buffer->size = gst_buffer_get_size(buffer); + pthread_mutex_unlock(&parser->mutex); return S_OK; } @@ -291,7 +305,6 @@ static NTSTATUS wg_parser_stream_copy_buffer(void *args) 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(params->data, stream->map_info.data + offset, size); @@ -307,12 +320,11 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) pthread_mutex_lock(&parser->mutex); - assert(stream->event.type == WG_PARSER_EVENT_BUFFER); + assert(stream->buffer); gst_buffer_unmap(stream->buffer, &stream->map_info); gst_buffer_unref(stream->buffer); stream->buffer = NULL; - stream->event.type = WG_PARSER_EVENT_NONE; pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&stream->event_empty_cond); @@ -459,13 +471,12 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) stream->flushing = true; pthread_cond_signal(&stream->event_empty_cond); - if (stream->event.type == WG_PARSER_EVENT_BUFFER) + if (stream->buffer) { gst_buffer_unmap(stream->buffer, &stream->map_info); gst_buffer_unref(stream->buffer); stream->buffer = NULL; } - stream->event.type = WG_PARSER_EVENT_NONE; pthread_mutex_unlock(&parser->mutex); } @@ -514,7 +525,6 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu { struct wg_parser_stream *stream = gst_pad_get_element_private(pad); struct wg_parser *parser = stream->parser; - struct wg_parser_event stream_event; GST_LOG("stream %p, buffer %p.", stream, buffer); @@ -524,27 +534,12 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu return GST_FLOW_OK; } - stream_event.type = WG_PARSER_EVENT_BUFFER; - - /* FIXME: Should we use gst_segment_to_stream_time_full()? Under what - * circumstances is the stream time not equal to the buffer PTS? Note that - * this will need modification to wg_parser_stream_notify_qos() as well. */ - - if ((stream_event.u.buffer.has_pts = GST_BUFFER_PTS_IS_VALID(buffer))) - stream_event.u.buffer.pts = GST_BUFFER_PTS(buffer) / 100; - if ((stream_event.u.buffer.has_duration = GST_BUFFER_DURATION_IS_VALID(buffer))) - stream_event.u.buffer.duration = GST_BUFFER_DURATION(buffer) / 100; - stream_event.u.buffer.discontinuity = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); - stream_event.u.buffer.preroll = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE); - stream_event.u.buffer.delta = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); - stream_event.u.buffer.size = gst_buffer_get_size(buffer); - /* Allow this buffer to be flushed by GStreamer. We are effectively * implementing a queue object here. */ pthread_mutex_lock(&parser->mutex); - while (!stream->flushing && stream->event.type != WG_PARSER_EVENT_NONE) + while (!stream->flushing && stream->buffer) pthread_cond_wait(&stream->event_empty_cond, &parser->mutex); if (stream->flushing) { @@ -562,7 +557,6 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu return GST_FLOW_ERROR; } - stream->event = stream_event; stream->buffer = buffer; pthread_mutex_unlock(&parser->mutex); @@ -1591,7 +1585,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_parser_stream_enable), X(wg_parser_stream_disable), - X(wg_parser_stream_get_event), + X(wg_parser_stream_get_buffer), X(wg_parser_stream_copy_buffer), X(wg_parser_stream_release_buffer), X(wg_parser_stream_notify_qos), diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 96de6f2a3ba..bfed0d1e0ca 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1825,7 +1825,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, { IWMReaderCallbackAdvanced *callback_advanced = stream->reader->callback_advanced; struct wg_parser_stream *wg_stream = stream->wg_stream; - struct wg_parser_event event; + struct wg_parser_buffer wg_buffer; DWORD size, capacity; INSSBuffer *sample; HRESULT hr; @@ -1839,7 +1839,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, for (;;) { - if (!wg_parser_stream_get_event(wg_stream, &event)) + if (!wg_parser_stream_get_buffer(wg_stream, &wg_buffer)) { stream->eos = true; TRACE("End of stream.\n"); @@ -1851,9 +1851,9 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, if (callback_advanced && stream->read_compressed && stream->allocate_stream) { if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForStream(callback_advanced, - stream->index + 1, event.u.buffer.size, &sample, NULL))) + stream->index + 1, wg_buffer.size, &sample, NULL))) { - ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr); + ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr); wg_parser_stream_release_buffer(wg_stream); return hr; } @@ -1861,9 +1861,9 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, else if (callback_advanced && !stream->read_compressed && stream->allocate_output) { if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced, - stream->index, event.u.buffer.size, &sample, NULL))) + stream->index, wg_buffer.size, &sample, NULL))) { - ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr); + ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr); wg_parser_stream_release_buffer(wg_stream); return hr; } @@ -1873,7 +1873,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, struct buffer *object; /* FIXME: Should these be pooled? */ - if (!(object = calloc(1, offsetof(struct buffer, data[event.u.buffer.size])))) + if (!(object = calloc(1, offsetof(struct buffer, data[wg_buffer.size])))) { wg_parser_stream_release_buffer(wg_stream); return E_OUTOFMEMORY; @@ -1881,7 +1881,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, object->INSSBuffer_iface.lpVtbl = &buffer_vtbl; object->refcount = 1; - object->capacity = event.u.buffer.size; + object->capacity = wg_buffer.size; TRACE("Created buffer %p.\n", object); sample = &object->INSSBuffer_iface; @@ -1891,32 +1891,32 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream, ERR("Failed to get data pointer, hr %#lx.\n", hr); if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity))) ERR("Failed to get capacity, hr %#lx.\n", hr); - if (event.u.buffer.size > capacity) - ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, event.u.buffer.size); + if (wg_buffer.size > capacity) + ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, wg_buffer.size); - if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, event.u.buffer.size)) + if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, wg_buffer.size)) { /* The GStreamer pin has been flushed. */ INSSBuffer_Release(sample); continue; } - if (FAILED(hr = INSSBuffer_SetLength(sample, event.u.buffer.size))) - ERR("Failed to set size %u, hr %#lx.\n", event.u.buffer.size, hr); + if (FAILED(hr = INSSBuffer_SetLength(sample, wg_buffer.size))) + ERR("Failed to set size %u, hr %#lx.\n", wg_buffer.size, hr); wg_parser_stream_release_buffer(wg_stream); - if (!event.u.buffer.has_pts) + if (!wg_buffer.has_pts) FIXME("Missing PTS.\n"); - if (!event.u.buffer.has_duration) + if (!wg_buffer.has_duration) FIXME("Missing duration.\n"); - *pts = event.u.buffer.pts; - *duration = event.u.buffer.duration; + *pts = wg_buffer.pts; + *duration = wg_buffer.duration; *flags = 0; - if (event.u.buffer.discontinuity) + if (wg_buffer.discontinuity) *flags |= WM_SF_DISCONTINUITY; - if (!event.u.buffer.delta) + if (!wg_buffer.delta) *flags |= WM_SF_CLEANPOINT; *ret_sample = sample;