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:
parent
0c59cfc14e
commit
a4be9e8568
|
@ -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_enable(struct wg_parser_stream *stream, const struct wg_format *format);
|
||||||
void wg_parser_stream_disable(struct wg_parser_stream *stream);
|
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,
|
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
|
||||||
void *data, uint32_t offset, uint32_t size);
|
void *data, uint32_t offset, uint32_t size);
|
||||||
void wg_parser_stream_release_buffer(struct wg_parser_stream *stream);
|
void wg_parser_stream_release_buffer(struct wg_parser_stream *stream);
|
||||||
|
|
|
@ -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);
|
__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,
|
.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,
|
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
|
||||||
|
|
|
@ -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);
|
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;
|
IMFMediaBuffer *buffer;
|
||||||
IMFSample *sample;
|
IMFSample *sample;
|
||||||
|
@ -463,7 +463,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even
|
||||||
return;
|
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);
|
ERR("Failed to create buffer, hr %#lx.\n", hr);
|
||||||
IMFSample_Release(sample);
|
IMFSample_Release(sample);
|
||||||
|
@ -476,7 +476,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even
|
||||||
goto out;
|
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);
|
ERR("Failed to set size, hr %#lx.\n", hr);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -488,7 +488,7 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even
|
||||||
goto out;
|
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);
|
wg_parser_stream_release_buffer(stream->wg_stream);
|
||||||
IMFMediaBuffer_Unlock(buffer);
|
IMFMediaBuffer_Unlock(buffer);
|
||||||
|
@ -502,13 +502,13 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even
|
||||||
goto out;
|
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);
|
ERR("Failed to set sample time, hr %#lx.\n", hr);
|
||||||
goto out;
|
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);
|
ERR("Failed to set sample duration, hr %#lx.\n", hr);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -528,13 +528,13 @@ out:
|
||||||
static void wait_on_sample(struct media_stream *stream, IUnknown *token)
|
static void wait_on_sample(struct media_stream *stream, IUnknown *token)
|
||||||
{
|
{
|
||||||
PROPVARIANT empty_var = {.vt = VT_EMPTY};
|
PROPVARIANT empty_var = {.vt = VT_EMPTY};
|
||||||
struct wg_parser_event event;
|
struct wg_parser_buffer buffer;
|
||||||
|
|
||||||
TRACE("%p, %p\n", stream, token);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -686,7 +686,7 @@ static uint64_t scale_uint64(uint64_t value, uint32_t numerator, uint32_t denomi
|
||||||
|
|
||||||
/* Fill and send a single IMediaSample. */
|
/* Fill and send a single IMediaSample. */
|
||||||
static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample,
|
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;
|
HRESULT hr;
|
||||||
BYTE *ptr = NULL;
|
BYTE *ptr = NULL;
|
||||||
|
@ -707,21 +707,21 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample,
|
||||||
return S_OK;
|
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)
|
if (offset)
|
||||||
start_pts += scale_uint64(offset, 10000000, bytes_per_second);
|
start_pts += scale_uint64(offset, 10000000, bytes_per_second);
|
||||||
start_pts -= pin->seek.llCurrent;
|
start_pts -= pin->seek.llCurrent;
|
||||||
start_pts *= pin->seek.dRate;
|
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)
|
if (offset + size < buffer->size)
|
||||||
end_pts = event->u.buffer.pts + scale_uint64(offset + size, 10000000, bytes_per_second);
|
end_pts = buffer->pts + scale_uint64(offset + size, 10000000, bytes_per_second);
|
||||||
end_pts -= pin->seek.llCurrent;
|
end_pts -= pin->seek.llCurrent;
|
||||||
end_pts *= pin->seek.dRate;
|
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_SetMediaTime(sample, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaSample_SetDiscontinuity(sample, !offset && event->u.buffer.discontinuity);
|
IMediaSample_SetDiscontinuity(sample, !offset && buffer->discontinuity);
|
||||||
IMediaSample_SetPreroll(sample, event->u.buffer.preroll);
|
IMediaSample_SetPreroll(sample, buffer->preroll);
|
||||||
IMediaSample_SetSyncPoint(sample, !event->u.buffer.delta);
|
IMediaSample_SetSyncPoint(sample, !buffer->delta);
|
||||||
|
|
||||||
if (!pin->pin.pin.peer)
|
if (!pin->pin.pin.peer)
|
||||||
return VFW_E_NOT_CONNECTED;
|
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
|
/* Send a single GStreamer buffer (splitting it into multiple IMediaSamples if
|
||||||
* necessary). */
|
* 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;
|
HRESULT hr;
|
||||||
IMediaSample *sample;
|
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;
|
WAVEFORMATEX *format = (WAVEFORMATEX *)pin->pin.pin.mt.pbFormat;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
while (offset < event->u.buffer.size)
|
while (offset < buffer->size)
|
||||||
{
|
{
|
||||||
uint32_t advance;
|
uint32_t advance;
|
||||||
|
|
||||||
|
@ -784,9 +784,9 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event
|
||||||
break;
|
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);
|
IMediaSample_Release(sample);
|
||||||
|
|
||||||
|
@ -804,7 +804,7 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event
|
||||||
}
|
}
|
||||||
else
|
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);
|
IMediaSample_Release(sample);
|
||||||
}
|
}
|
||||||
|
@ -822,7 +822,7 @@ static DWORD CALLBACK stream_thread(void *arg)
|
||||||
|
|
||||||
while (filter->streaming)
|
while (filter->streaming)
|
||||||
{
|
{
|
||||||
struct wg_parser_event event;
|
struct wg_parser_buffer buffer;
|
||||||
|
|
||||||
EnterCriticalSection(&pin->flushing_cs);
|
EnterCriticalSection(&pin->flushing_cs);
|
||||||
|
|
||||||
|
@ -833,9 +833,9 @@ static DWORD CALLBACK stream_thread(void *arg)
|
||||||
continue;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -844,8 +844,6 @@ static DWORD CALLBACK stream_thread(void *arg)
|
||||||
pin->eos = true;
|
pin->eos = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Got event of type %#x.\n", event.type);
|
|
||||||
|
|
||||||
LeaveCriticalSection(&pin->flushing_cs);
|
LeaveCriticalSection(&pin->flushing_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,27 +103,14 @@ struct wg_format
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wg_parser_event_type
|
struct wg_parser_buffer
|
||||||
{
|
{
|
||||||
WG_PARSER_EVENT_NONE = 0,
|
|
||||||
WG_PARSER_EVENT_BUFFER,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wg_parser_event
|
|
||||||
{
|
|
||||||
enum wg_parser_event_type type;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
/* pts and duration are in 100-nanosecond units. */
|
/* pts and duration are in 100-nanosecond units. */
|
||||||
ULONGLONG pts, duration;
|
UINT64 pts, duration;
|
||||||
uint32_t size;
|
UINT32 size;
|
||||||
bool discontinuity, preroll, delta, has_pts, has_duration;
|
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
|
enum wg_parser_type
|
||||||
{
|
{
|
||||||
|
@ -185,10 +172,10 @@ struct wg_parser_stream_enable_params
|
||||||
const struct wg_format *format;
|
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_stream *stream;
|
||||||
struct wg_parser_event *event;
|
struct wg_parser_buffer *buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wg_parser_stream_copy_buffer_params
|
struct wg_parser_stream_copy_buffer_params
|
||||||
|
@ -247,7 +234,7 @@ enum unix_funcs
|
||||||
unix_wg_parser_stream_enable,
|
unix_wg_parser_stream_enable,
|
||||||
unix_wg_parser_stream_disable,
|
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_copy_buffer,
|
||||||
unix_wg_parser_stream_release_buffer,
|
unix_wg_parser_stream_release_buffer,
|
||||||
unix_wg_parser_stream_notify_qos,
|
unix_wg_parser_stream_notify_qos,
|
||||||
|
|
|
@ -102,7 +102,6 @@ struct wg_parser_stream
|
||||||
struct wg_format preferred_format, current_format;
|
struct wg_format preferred_format, current_format;
|
||||||
|
|
||||||
pthread_cond_t event_cond, event_empty_cond;
|
pthread_cond_t event_cond, event_empty_cond;
|
||||||
struct wg_parser_event event;
|
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstMapInfo map_info;
|
GstMapInfo map_info;
|
||||||
|
|
||||||
|
@ -251,22 +250,37 @@ static NTSTATUS wg_parser_stream_disable(void *args)
|
||||||
return S_OK;
|
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_stream *stream = params->stream;
|
||||||
struct wg_parser *parser = stream->parser;
|
struct wg_parser *parser = stream->parser;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
pthread_mutex_lock(&parser->mutex);
|
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);
|
pthread_cond_wait(&stream->event_cond, &parser->mutex);
|
||||||
|
|
||||||
/* Note that we can both have a buffer and stream->eos, in which case we
|
/* Note that we can both have a buffer and stream->eos, in which case we
|
||||||
* must return the buffer. */
|
* 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);
|
pthread_mutex_unlock(&parser->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +305,6 @@ static NTSTATUS wg_parser_stream_copy_buffer(void *args)
|
||||||
return VFW_E_WRONG_STATE;
|
return VFW_E_WRONG_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(stream->event.type == WG_PARSER_EVENT_BUFFER);
|
|
||||||
assert(offset < stream->map_info.size);
|
assert(offset < stream->map_info.size);
|
||||||
assert(offset + size <= stream->map_info.size);
|
assert(offset + size <= stream->map_info.size);
|
||||||
memcpy(params->data, stream->map_info.data + offset, 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);
|
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_unmap(stream->buffer, &stream->map_info);
|
||||||
gst_buffer_unref(stream->buffer);
|
gst_buffer_unref(stream->buffer);
|
||||||
stream->buffer = NULL;
|
stream->buffer = NULL;
|
||||||
stream->event.type = WG_PARSER_EVENT_NONE;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&parser->mutex);
|
pthread_mutex_unlock(&parser->mutex);
|
||||||
pthread_cond_signal(&stream->event_empty_cond);
|
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;
|
stream->flushing = true;
|
||||||
pthread_cond_signal(&stream->event_empty_cond);
|
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_unmap(stream->buffer, &stream->map_info);
|
||||||
gst_buffer_unref(stream->buffer);
|
gst_buffer_unref(stream->buffer);
|
||||||
stream->buffer = NULL;
|
stream->buffer = NULL;
|
||||||
}
|
}
|
||||||
stream->event.type = WG_PARSER_EVENT_NONE;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&parser->mutex);
|
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_stream *stream = gst_pad_get_element_private(pad);
|
||||||
struct wg_parser *parser = stream->parser;
|
struct wg_parser *parser = stream->parser;
|
||||||
struct wg_parser_event stream_event;
|
|
||||||
|
|
||||||
GST_LOG("stream %p, buffer %p.", stream, buffer);
|
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;
|
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
|
/* Allow this buffer to be flushed by GStreamer. We are effectively
|
||||||
* implementing a queue object here. */
|
* implementing a queue object here. */
|
||||||
|
|
||||||
pthread_mutex_lock(&parser->mutex);
|
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);
|
pthread_cond_wait(&stream->event_empty_cond, &parser->mutex);
|
||||||
if (stream->flushing)
|
if (stream->flushing)
|
||||||
{
|
{
|
||||||
|
@ -562,7 +557,6 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->event = stream_event;
|
|
||||||
stream->buffer = buffer;
|
stream->buffer = buffer;
|
||||||
|
|
||||||
pthread_mutex_unlock(&parser->mutex);
|
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_enable),
|
||||||
X(wg_parser_stream_disable),
|
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_copy_buffer),
|
||||||
X(wg_parser_stream_release_buffer),
|
X(wg_parser_stream_release_buffer),
|
||||||
X(wg_parser_stream_notify_qos),
|
X(wg_parser_stream_notify_qos),
|
||||||
|
|
|
@ -1825,7 +1825,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
{
|
{
|
||||||
IWMReaderCallbackAdvanced *callback_advanced = stream->reader->callback_advanced;
|
IWMReaderCallbackAdvanced *callback_advanced = stream->reader->callback_advanced;
|
||||||
struct wg_parser_stream *wg_stream = stream->wg_stream;
|
struct wg_parser_stream *wg_stream = stream->wg_stream;
|
||||||
struct wg_parser_event event;
|
struct wg_parser_buffer wg_buffer;
|
||||||
DWORD size, capacity;
|
DWORD size, capacity;
|
||||||
INSSBuffer *sample;
|
INSSBuffer *sample;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1839,7 +1839,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!wg_parser_stream_get_event(wg_stream, &event))
|
if (!wg_parser_stream_get_buffer(wg_stream, &wg_buffer))
|
||||||
{
|
{
|
||||||
stream->eos = true;
|
stream->eos = true;
|
||||||
TRACE("End of stream.\n");
|
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 (callback_advanced && stream->read_compressed && stream->allocate_stream)
|
||||||
{
|
{
|
||||||
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForStream(callback_advanced,
|
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);
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
return hr;
|
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)
|
else if (callback_advanced && !stream->read_compressed && stream->allocate_output)
|
||||||
{
|
{
|
||||||
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
|
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);
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -1873,7 +1873,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
struct buffer *object;
|
struct buffer *object;
|
||||||
|
|
||||||
/* FIXME: Should these be pooled? */
|
/* 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);
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
@ -1881,7 +1881,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
|
|
||||||
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
|
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
|
||||||
object->refcount = 1;
|
object->refcount = 1;
|
||||||
object->capacity = event.u.buffer.size;
|
object->capacity = wg_buffer.size;
|
||||||
|
|
||||||
TRACE("Created buffer %p.\n", object);
|
TRACE("Created buffer %p.\n", object);
|
||||||
sample = &object->INSSBuffer_iface;
|
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);
|
ERR("Failed to get data pointer, hr %#lx.\n", hr);
|
||||||
if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
|
if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
|
||||||
ERR("Failed to get capacity, hr %#lx.\n", hr);
|
ERR("Failed to get capacity, hr %#lx.\n", hr);
|
||||||
if (event.u.buffer.size > capacity)
|
if (wg_buffer.size > capacity)
|
||||||
ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, event.u.buffer.size);
|
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. */
|
/* The GStreamer pin has been flushed. */
|
||||||
INSSBuffer_Release(sample);
|
INSSBuffer_Release(sample);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr = INSSBuffer_SetLength(sample, event.u.buffer.size)))
|
if (FAILED(hr = INSSBuffer_SetLength(sample, wg_buffer.size)))
|
||||||
ERR("Failed to set size %u, hr %#lx.\n", event.u.buffer.size, hr);
|
ERR("Failed to set size %u, hr %#lx.\n", wg_buffer.size, hr);
|
||||||
|
|
||||||
wg_parser_stream_release_buffer(wg_stream);
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
|
|
||||||
if (!event.u.buffer.has_pts)
|
if (!wg_buffer.has_pts)
|
||||||
FIXME("Missing PTS.\n");
|
FIXME("Missing PTS.\n");
|
||||||
if (!event.u.buffer.has_duration)
|
if (!wg_buffer.has_duration)
|
||||||
FIXME("Missing duration.\n");
|
FIXME("Missing duration.\n");
|
||||||
|
|
||||||
*pts = event.u.buffer.pts;
|
*pts = wg_buffer.pts;
|
||||||
*duration = event.u.buffer.duration;
|
*duration = wg_buffer.duration;
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
if (event.u.buffer.discontinuity)
|
if (wg_buffer.discontinuity)
|
||||||
*flags |= WM_SF_DISCONTINUITY;
|
*flags |= WM_SF_DISCONTINUITY;
|
||||||
if (!event.u.buffer.delta)
|
if (!wg_buffer.delta)
|
||||||
*flags |= WM_SF_CLEANPOINT;
|
*flags |= WM_SF_CLEANPOINT;
|
||||||
|
|
||||||
*ret_sample = sample;
|
*ret_sample = sample;
|
||||||
|
|
Loading…
Reference in New Issue