winegstreamer: Flatten wg_parser_event into a wg_parser_buffer structure.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2022-02-23 15:46:50 -06:00 committed by Alexandre Julliard
parent 0c59cfc14e
commit a4be9e8568
7 changed files with 84 additions and 105 deletions

View File

@ -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);

View File

@ -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, &params);
return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_buffer, &params);
}
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,

View File

@ -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
{

View File

@ -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);
}

View File

@ -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,

View File

@ -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),

View File

@ -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;