Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 143 ++++++++++++++++------------------ 1 file changed, 65 insertions(+), 78 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 1ddbc954fb4..9f733396d92 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -56,6 +56,8 @@ struct wg_parser
pthread_t push_thread;
+ pthread_mutex_t mutex; + pthread_cond_t init_cond; bool no_more_pads, has_duration, error;
@@ -95,8 +97,6 @@ struct parser
uint64_t next_pull_offset;
- pthread_mutex_t mutex; - HANDLE read_thread;
BOOL (*init_gst)(struct parser *filter); @@ -706,7 +706,7 @@ static gboolean event_src(GstPad *pad, GstObject *parent, GstEvent *event)
static GstFlowReturn queue_stream_event(struct parser_source *pin, const struct parser_event *event) { - struct parser *filter = impl_from_strmbase_filter(pin->pin.pin.filter); + struct wg_parser *parser = impl_from_strmbase_filter(pin->pin.pin.filter)->wg_parser;
/* Unlike request_buffer_src() [q.v.], we need to watch for GStreamer * flushes here. The difference is that we can be blocked by the streaming @@ -714,17 +714,17 @@ static GstFlowReturn queue_stream_event(struct parser_source *pin, const struct * request_buffer_src() can only be blocked by the upstream source, and that * is solved by flushing the upstream source. */
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); while (!pin->flushing && pin->event.type != PARSER_EVENT_NONE) - pthread_cond_wait(&pin->event_empty_cond, &filter->mutex); + pthread_cond_wait(&pin->event_empty_cond, &parser->mutex); if (pin->flushing) { - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); GST_DEBUG("Filter is flushing; discarding event."); return GST_FLOW_FLUSHING; } pin->event = *event; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&pin->event_cond); GST_LOG("Event queued."); return GST_FLOW_OK; @@ -774,9 +774,9 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) } else { - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); pin->eos = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); } break; @@ -784,7 +784,7 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) case GST_EVENT_FLUSH_START: if (pin->pin.pin.peer) { - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex);
pin->flushing = true; pthread_cond_signal(&pin->event_empty_cond); @@ -802,7 +802,7 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) } pin->event.type = PARSER_EVENT_NONE;
- pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); } break;
@@ -810,9 +810,9 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) gst_segment_init(pin->segment, GST_FORMAT_TIME); if (pin->pin.pin.peer) { - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); pin->flushing = false; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); } break;
@@ -821,9 +821,9 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) GstCaps *caps;
gst_event_parse_caps(event, &caps); - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); gst_caps_replace(&pin->caps, caps); - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); break; } @@ -1041,14 +1041,14 @@ static bool get_stream_event(struct parser_source *pin, struct parser_event *eve struct parser *filter = impl_from_strmbase_filter(pin->pin.pin.filter); struct wg_parser *parser = filter->wg_parser;
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex);
while (!parser->flushing && pin->event.type == PARSER_EVENT_NONE) - pthread_cond_wait(&pin->event_cond, &filter->mutex); + pthread_cond_wait(&pin->event_cond, &parser->mutex);
if (parser->flushing) { - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); TRACE("Filter is flushing.\n"); return false; } @@ -1056,7 +1056,7 @@ static bool get_stream_event(struct parser_source *pin, struct parser_event *eve *event = pin->event; pin->event.type = PARSER_EVENT_NONE;
- pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&pin->event_empty_cond);
return true; @@ -1121,7 +1121,7 @@ static GstFlowReturn request_buffer_src(GstPad *pad, GstObject *parent, guint64 if (!*buffer) *buffer = new_buffer = gst_buffer_new_and_alloc(size);
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex);
assert(!parser->read_request.buffer); parser->read_request.buffer = *buffer; @@ -1135,11 +1135,11 @@ static GstFlowReturn request_buffer_src(GstPad *pad, GstObject *parent, guint64 * read_thread() not running. */
while (!parser->read_request.done) - pthread_cond_wait(&parser->read_done_cond, &filter->mutex); + pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
ret = parser->read_request.ret;
- pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
GST_LOG("Request returned %s.", gst_flow_get_name(ret));
@@ -1186,12 +1186,12 @@ static DWORD CALLBACK read_thread(void *arg)
TRACE("Starting read thread for filter %p.\n", filter);
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex);
while (filter->sink_connected) { while (parser->sink_connected && !parser->read_request.buffer) - pthread_cond_wait(&parser->read_cond, &filter->mutex); + pthread_cond_wait(&parser->read_cond, &parser->mutex);
if (!parser->sink_connected) break; @@ -1203,7 +1203,7 @@ static DWORD CALLBACK read_thread(void *arg) pthread_cond_signal(&parser->read_done_cond); }
- pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
TRACE("Streaming stopped; exiting.\n"); return 0; @@ -1488,9 +1488,9 @@ static void no_more_pads(GstElement *decodebin, gpointer user)
GST_DEBUG("filter %p.", filter);
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->no_more_pads = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); }
@@ -1530,9 +1530,9 @@ static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) fprintf(stderr, "winegstreamer: error: %s: %s\n", GST_OBJECT_NAME(msg->src), dbg_info); g_error_free(err); g_free(dbg_info); - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->error = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); break;
@@ -1545,9 +1545,9 @@ static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) break;
case GST_MESSAGE_DURATION_CHANGED: - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->has_duration = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); break;
@@ -1619,7 +1619,7 @@ static HRESULT GST_Connect(struct parser *This, IPin *pConnectPin) if (!This->init_gst(This)) return E_FAIL;
- pthread_mutex_lock(&This->mutex); + pthread_mutex_lock(&parser->mutex);
for (i = 0; i < This->source_count; ++i) { @@ -1628,15 +1628,15 @@ static HRESULT GST_Connect(struct parser *This, IPin *pConnectPin) pin->seek.llDuration = pin->seek.llStop = query_duration(pin->their_src); pin->seek.llCurrent = 0; while (!pin->caps && !parser->error) - pthread_cond_wait(&parser->init_cond, &This->mutex); + pthread_cond_wait(&parser->init_cond, &parser->mutex); if (parser->error) { - pthread_mutex_unlock(&This->mutex); + pthread_mutex_unlock(&parser->mutex); return E_FAIL; } }
- pthread_mutex_unlock(&This->mutex); + pthread_mutex_unlock(&parser->mutex);
parser->next_offset = 0; This->next_pull_offset = 0; @@ -1677,6 +1677,7 @@ static void wg_parser_destroy(struct wg_parser *parser) gst_object_unref(parser->bus); }
+ pthread_mutex_destroy(&parser->mutex); pthread_cond_destroy(&parser->init_cond); pthread_cond_destroy(&parser->read_cond); pthread_cond_destroy(&parser->read_done_cond); @@ -1704,8 +1705,6 @@ static void parser_destroy(struct strmbase_filter *iface)
wg_parser_destroy(filter->wg_parser);
- pthread_mutex_destroy(&filter->mutex); - strmbase_sink_cleanup(&filter->sink); strmbase_filter_cleanup(&filter->filter); heap_free(filter); @@ -1723,9 +1722,9 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface) return S_OK;
filter->streaming = true; - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->flushing = false; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
/* DirectShow retains the old seek positions, but resets to them every time * it transitions from stopped -> paused. */ @@ -1764,9 +1763,9 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface) return S_OK;
filter->streaming = false; - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->flushing = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
for (i = 0; i < filter->source_count; ++i) { @@ -1878,9 +1877,9 @@ static BOOL decodebin_parser_init_gst(struct parser *filter)
parser->their_sink = gst_element_get_static_pad(element, "sink");
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->no_more_pads = parser->error = false; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0) { @@ -1896,15 +1895,15 @@ static BOOL decodebin_parser_init_gst(struct parser *filter) return FALSE; }
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); while (!parser->no_more_pads && !parser->error) - pthread_cond_wait(&parser->init_cond, &filter->mutex); + pthread_cond_wait(&parser->init_cond, &parser->mutex); if (parser->error) { - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return FALSE; } - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return TRUE; }
@@ -1998,11 +1997,6 @@ static BOOL parser_init_gstreamer(void) return TRUE; }
-static void parser_init_common(struct parser *object) -{ - pthread_mutex_init(&object->mutex, NULL); -} - static struct wg_parser *wg_parser_create(void) { struct wg_parser *parser; @@ -2010,6 +2004,7 @@ static struct wg_parser *wg_parser_create(void) if (!(parser = calloc(1, sizeof(*parser)))) return NULL;
+ 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); @@ -2037,8 +2032,6 @@ HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY; }
- parser_init_common(object); - strmbase_filter_init(&object->filter, outer, &CLSID_decodebin_parser, &filter_ops); strmbase_sink_init(&object->sink, &object->filter, wcsInputPinName, &sink_ops, NULL);
@@ -2172,9 +2165,9 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (!(current_flags & AM_SEEKING_NoFlush)) { - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->flushing = true; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
for (i = 0; i < filter->source_count; ++i) { @@ -2221,9 +2214,9 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (!(current_flags & AM_SEEKING_NoFlush)) { - pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->flushing = false; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
for (i = 0; i < filter->source_count; ++i) { @@ -2526,13 +2519,13 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) return S_OK;
/* Unblock all of our streams. */ - pthread_mutex_lock(&This->mutex); + pthread_mutex_lock(&parser->mutex); for (i = 0; i < This->source_count; ++i) { This->sources[i]->flushing = true; pthread_cond_signal(&This->sources[i]->event_empty_cond); } - pthread_mutex_unlock(&This->mutex); + pthread_mutex_unlock(&parser->mutex);
gst_element_set_state(parser->container, GST_STATE_NULL); gst_pad_unlink(parser->my_src, parser->their_sink); @@ -2543,9 +2536,9 @@ static HRESULT GST_RemoveOutputPins(struct parser *This) /* read_thread() needs to stay alive to service any read requests GStreamer * sends, so we can only shut it down after GStreamer stops. */ This->sink_connected = false; - pthread_mutex_lock(&This->mutex); + pthread_mutex_lock(&parser->mutex); parser->sink_connected = false; - pthread_mutex_unlock(&This->mutex); + pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->read_cond); WaitForSingleObject(This->read_thread, INFINITE); CloseHandle(This->read_thread); @@ -2701,8 +2694,6 @@ HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY; }
- parser_init_common(object); - strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops); strmbase_sink_init(&object->sink, &object->filter, sink_name, &wave_parser_sink_ops, NULL); object->init_gst = wave_parser_init_gst; @@ -2750,9 +2741,9 @@ static BOOL avi_splitter_init_gst(struct parser *filter)
parser->their_sink = gst_element_get_static_pad(element, "sink");
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); parser->no_more_pads = parser->error = false; - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex);
if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0) { @@ -2768,15 +2759,15 @@ static BOOL avi_splitter_init_gst(struct parser *filter) return FALSE; }
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); while (!parser->no_more_pads && !parser->error) - pthread_cond_wait(&parser->init_cond, &filter->mutex); + pthread_cond_wait(&parser->init_cond, &parser->mutex); if (parser->error) { - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return FALSE; } - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return TRUE; }
@@ -2821,8 +2812,6 @@ HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY; }
- parser_init_common(object); - strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops); strmbase_sink_init(&object->sink, &object->filter, sink_name, &avi_splitter_sink_ops, NULL); object->init_gst = avi_splitter_init_gst; @@ -2896,15 +2885,15 @@ static BOOL mpeg_splitter_init_gst(struct parser *filter) return FALSE; }
- pthread_mutex_lock(&filter->mutex); + pthread_mutex_lock(&parser->mutex); while (!parser->has_duration && !parser->error && !pin->eos) - pthread_cond_wait(&parser->init_cond, &filter->mutex); + pthread_cond_wait(&parser->init_cond, &parser->mutex); if (parser->error) { - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return FALSE; } - pthread_mutex_unlock(&filter->mutex); + pthread_mutex_unlock(&parser->mutex); return TRUE; }
@@ -2972,8 +2961,6 @@ HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY; }
- parser_init_common(object); - strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops); strmbase_sink_init(&object->sink, &object->filter, sink_name, &mpeg_splitter_sink_ops, NULL); object->IAMStreamSelect_iface.lpVtbl = &stream_select_vtbl;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 36 +++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 9f733396d92..b8038af0524 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -74,6 +74,11 @@ struct wg_parser bool flushing, sink_connected; };
+struct wg_parser_stream +{ + GstSegment *segment; +}; + struct parser { struct strmbase_filter filter; @@ -131,9 +136,10 @@ struct parser_source struct strmbase_source pin; IQualityControl IQualityControl_iface;
+ struct wg_parser_stream *wg_stream; + GstPad *their_src, *post_sink, *post_src, *my_sink; GstElement *flip; - GstSegment *segment; GstCaps *caps; SourceSeeking seek;
@@ -733,6 +739,7 @@ static GstFlowReturn queue_stream_event(struct parser_source *pin, const struct static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) { struct parser_source *pin = gst_pad_get_element_private(pad); + struct wg_parser_stream *stream = pin->wg_stream; struct parser *filter = impl_from_strmbase_filter(pin->pin.pin.filter); struct wg_parser *parser = filter->wg_parser;
@@ -754,7 +761,7 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) break; }
- gst_segment_copy_into(segment, pin->segment); + gst_segment_copy_into(segment, stream->segment);
stream_event.type = PARSER_EVENT_SEGMENT; stream_event.u.segment.position = segment->position / 100; @@ -807,7 +814,7 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) break;
case GST_EVENT_FLUSH_STOP: - gst_segment_init(pin->segment, GST_FORMAT_TIME); + gst_segment_init(stream->segment, GST_FORMAT_TIME); if (pin->pin.pin.peer) { pthread_mutex_lock(&parser->mutex); @@ -913,6 +920,7 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *bu static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, GstBuffer *buf, GstMapInfo *info, gsize offset, gsize size, DWORD bytes_per_second) { + struct wg_parser_stream *stream = pin->wg_stream; HRESULT hr; BYTE *ptr = NULL;
@@ -931,7 +939,7 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, GstClockTime ptsStart = buf->pts; if (offset > 0) ptsStart = buf->pts + gst_util_uint64_scale(offset, GST_SECOND, bytes_per_second); - rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, ptsStart); + rtStart = gst_segment_to_running_time(stream->segment, GST_FORMAT_TIME, ptsStart); if (rtStart >= 0) rtStart /= 100;
@@ -944,7 +952,7 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample, ptsStop = buf->pts + gst_util_uint64_scale(offset + size, GST_SECOND, bytes_per_second); tStart = ptsStart / 100; tStop = ptsStop / 100; - rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, ptsStop); + rtStop = gst_segment_to_running_time(stream->segment, GST_FORMAT_TIME, ptsStop); if (rtStop >= 0) rtStop /= 100; TRACE("Current time on %p: %i to %i ms\n", pin, (int)(rtStart / 10000), (int)(rtStop / 10000)); @@ -2426,6 +2434,8 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
static void free_source_pin(struct parser_source *pin) { + struct wg_parser_stream *stream = pin->wg_stream; + if (pin->pin.pin.peer) { if (SUCCEEDED(IMemAllocator_Decommit(pin->pin.pAllocator))) @@ -2448,11 +2458,13 @@ static void free_source_pin(struct parser_source *pin) gst_object_unref(pin->their_src); } gst_object_unref(pin->my_sink); - gst_segment_free(pin->segment); + gst_segment_free(stream->segment);
pthread_cond_destroy(&pin->event_cond); pthread_cond_destroy(&pin->event_empty_cond);
+ free(stream); + pin->flushing_cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&pin->flushing_cs);
@@ -2474,6 +2486,7 @@ static const struct strmbase_source_ops source_ops = static struct parser_source *create_pin(struct parser *filter, const WCHAR *name) { struct parser_source *pin, **new_array; + struct wg_parser_stream *stream; char pad_name[19];
if (!(new_array = heap_realloc(filter->sources, (filter->source_count + 1) * sizeof(*new_array)))) @@ -2483,9 +2496,16 @@ static struct parser_source *create_pin(struct parser *filter, const WCHAR *name if (!(pin = heap_alloc_zero(sizeof(*pin)))) return NULL;
+ if (!(stream = calloc(1, sizeof(*stream)))) + { + heap_free(pin); + return NULL; + } + pin->wg_stream = stream; + strmbase_source_init(&pin->pin, &filter->filter, name, &source_ops); - pin->segment = gst_segment_new(); - gst_segment_init(pin->segment, GST_FORMAT_TIME); + stream->segment = gst_segment_new(); + gst_segment_init(stream->segment, GST_FORMAT_TIME); pin->IQualityControl_iface.lpVtbl = &GSTOutPin_QualityControl_Vtbl; strmbase_seeking_init(&pin->seek, &GST_Seeking_Vtbl, GST_ChangeStop, GST_ChangeCurrent, GST_ChangeRate);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 115 +++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 52 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index b8038af0524..5277a9fa3b9 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -76,6 +76,7 @@ struct wg_parser
struct wg_parser_stream { + GstPad *their_src, *post_sink, *post_src, *my_sink; GstSegment *segment; };
@@ -138,7 +139,6 @@ struct parser_source
struct wg_parser_stream *wg_stream;
- GstPad *their_src, *post_sink, *post_src, *my_sink; GstElement *flip; GstCaps *caps; SourceSeeking seek; @@ -1227,16 +1227,16 @@ static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user)
for (i = 0; i < filter->source_count; ++i) { - struct parser_source *pin = filter->sources[i]; + struct wg_parser_stream *stream = filter->sources[i]->wg_stream;
- if (pin->their_src == pad) + if (stream->their_src == pad) { - if (pin->post_sink) - gst_pad_unlink(pin->their_src, pin->post_sink); + if (stream->post_sink) + gst_pad_unlink(stream->their_src, stream->post_sink); else - gst_pad_unlink(pin->their_src, pin->my_sink); - gst_object_unref(pin->their_src); - pin->their_src = NULL; + gst_pad_unlink(stream->their_src, stream->my_sink); + gst_object_unref(stream->their_src); + stream->their_src = NULL; return; } } @@ -1250,6 +1250,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct parser *Th { static const WCHAR formatW[] = {'S','t','r','e','a','m',' ','%','0','2','u',0}; struct wg_parser *parser = This->wg_parser; + struct wg_parser_stream *stream; const char *typename; char *name; GstCaps *caps; @@ -1276,6 +1277,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct parser *Th ERR("Failed to allocate memory.\n"); goto out; } + stream = pin->wg_stream;
if (!strcmp(typename, "video/x-raw")) { @@ -1331,8 +1333,8 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct parser *Th gst_element_link(vconv, flip); gst_element_link(flip, vconv2);
- pin->post_sink = gst_element_get_static_pad(deinterlace, "sink"); - pin->post_src = gst_element_get_static_pad(vconv2, "src"); + stream->post_sink = gst_element_get_static_pad(deinterlace, "sink"); + stream->post_src = gst_element_get_static_pad(vconv2, "src"); pin->flip = flip; } else if (!strcmp(typename, "audio/x-raw")) @@ -1353,41 +1355,41 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct parser *Th gst_bin_add(GST_BIN(parser->container), convert); gst_element_sync_state_with_parent(convert);
- pin->post_sink = gst_element_get_static_pad(convert, "sink"); - pin->post_src = gst_element_get_static_pad(convert, "src"); + stream->post_sink = gst_element_get_static_pad(convert, "sink"); + stream->post_src = gst_element_get_static_pad(convert, "src"); }
- if (pin->post_sink) + if (stream->post_sink) { - if ((ret = gst_pad_link(pad, pin->post_sink)) < 0) + if ((ret = gst_pad_link(pad, stream->post_sink)) < 0) { ERR("Failed to link decodebin source pad to post-processing elements, error %s.\n", gst_pad_link_get_name(ret)); - gst_object_unref(pin->post_sink); - pin->post_sink = NULL; + gst_object_unref(stream->post_sink); + stream->post_sink = NULL; goto out; }
- if ((ret = gst_pad_link(pin->post_src, pin->my_sink)) < 0) + if ((ret = gst_pad_link(stream->post_src, stream->my_sink)) < 0) { ERR("Failed to link post-processing elements to our sink pad, error %s.\n", gst_pad_link_get_name(ret)); - gst_object_unref(pin->post_src); - pin->post_src = NULL; - gst_object_unref(pin->post_sink); - pin->post_sink = NULL; + gst_object_unref(stream->post_src); + stream->post_src = NULL; + gst_object_unref(stream->post_sink); + stream->post_sink = NULL; goto out; } } - else if ((ret = gst_pad_link(pad, pin->my_sink)) < 0) + else if ((ret = gst_pad_link(pad, stream->my_sink)) < 0) { ERR("Failed to link decodebin source pad to our sink pad, error %s.\n", gst_pad_link_get_name(ret)); goto out; }
- gst_pad_set_active(pin->my_sink, 1); - gst_object_ref(pin->their_src = pad); + gst_pad_set_active(stream->my_sink, 1); + gst_object_ref(stream->their_src = pad); out: gst_caps_unref(caps); } @@ -1632,8 +1634,9 @@ static HRESULT GST_Connect(struct parser *This, IPin *pConnectPin) for (i = 0; i < This->source_count; ++i) { struct parser_source *pin = This->sources[i]; + struct wg_parser_stream *stream = pin->wg_stream;
- pin->seek.llDuration = pin->seek.llStop = query_duration(pin->their_src); + pin->seek.llDuration = pin->seek.llStop = query_duration(stream->their_src); pin->seek.llCurrent = 0; while (!pin->caps && !parser->error) pthread_cond_wait(&parser->init_cond, &parser->mutex); @@ -1740,7 +1743,7 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface) seeking = &filter->sources[0]->seek; if (seeking->llStop && seeking->llStop != seeking->llDuration) stop_type = GST_SEEK_TYPE_SET; - gst_pad_push_event(filter->sources[0]->my_sink, gst_event_new_seek( + gst_pad_push_event(filter->sources[0]->wg_stream->my_sink, gst_event_new_seek( seeking->dRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, seeking->llCurrent * 100, stop_type, seeking->llStop * 100)); @@ -2123,10 +2126,11 @@ static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface) static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) { struct parser_source *This = impl_from_IMediaSeeking(iface); + struct wg_parser_stream *stream = This->wg_stream; GstEvent *ev = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1); TRACE("(%p) New rate %g\n", This, This->seek.dRate); mark_wine_thread(); - gst_pad_push_event(This->my_sink, ev); + gst_pad_push_event(stream->my_sink, ev); return S_OK; }
@@ -2153,6 +2157,7 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface, { GstSeekType current_type = GST_SEEK_TYPE_SET, stop_type = GST_SEEK_TYPE_SET; struct parser_source *pin = impl_from_IMediaSeeking(iface); + struct wg_parser_stream *stream = pin->wg_stream; struct parser *filter = impl_from_strmbase_filter(pin->pin.pin.filter); struct wg_parser *parser = filter->wg_parser; GstSeekFlags flags = 0; @@ -2212,7 +2217,7 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface, if ((stop_flags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning) stop_type = GST_SEEK_TYPE_NONE;
- if (!gst_pad_push_event(pin->my_sink, gst_event_new_seek(pin->seek.dRate, GST_FORMAT_TIME, flags, + if (!gst_pad_push_event(stream->my_sink, gst_event_new_seek(pin->seek.dRate, GST_FORMAT_TIME, flags, current_type, pin->seek.llCurrent * 100, stop_type, pin->seek.llStop * 100))) { ERR("Failed to seek (current %s, stop %s).\n", @@ -2296,6 +2301,7 @@ static ULONG WINAPI GST_QualityControl_Release(IQualityControl *iface) static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q) { struct parser_source *pin = impl_from_IQualityControl(iface); + struct wg_parser_stream *stream = pin->wg_stream; GstQOSType type = GST_QOS_TYPE_OVERFLOW; GstClockTime timestamp; GstClockTimeDiff diff; @@ -2343,7 +2349,7 @@ static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFil if (!(event = gst_event_new_qos(type, 1000.0 / q.Proportion, diff, timestamp))) ERR("Failed to create QOS event.\n");
- gst_pad_push_event(pin->my_sink, event); + gst_pad_push_event(stream->my_sink, event);
return S_OK; } @@ -2402,6 +2408,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, IMemAllocator *allocator, ALLOCATOR_PROPERTIES *props) { struct parser_source *pin = impl_source_from_IPin(&iface->pin.IPin_iface); + struct wg_parser_stream *stream = pin->wg_stream; unsigned int buffer_size = 16384; ALLOCATOR_PROPERTIES ret_props;
@@ -2422,7 +2429,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, buffer_size = format->nAvgBytesPerSec; }
- gst_pad_push_event(pin->my_sink, gst_event_new_reconfigure()); + gst_pad_push_event(stream->my_sink, gst_event_new_reconfigure()); /* 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(). */
@@ -2443,21 +2450,21 @@ static void free_source_pin(struct parser_source *pin) IPin_Disconnect(&pin->pin.pin.IPin_iface); }
- if (pin->their_src) + if (stream->their_src) { - if (pin->post_sink) + if (stream->post_sink) { - gst_pad_unlink(pin->their_src, pin->post_sink); - gst_pad_unlink(pin->post_src, pin->my_sink); - gst_object_unref(pin->post_src); - gst_object_unref(pin->post_sink); - pin->post_src = pin->post_sink = NULL; + gst_pad_unlink(stream->their_src, stream->post_sink); + gst_pad_unlink(stream->post_src, stream->my_sink); + gst_object_unref(stream->post_src); + gst_object_unref(stream->post_sink); + stream->post_src = stream->post_sink = NULL; } else - gst_pad_unlink(pin->their_src, pin->my_sink); - gst_object_unref(pin->their_src); + gst_pad_unlink(stream->their_src, stream->my_sink); + gst_object_unref(stream->their_src); } - gst_object_unref(pin->my_sink); + gst_object_unref(stream->my_sink); gst_segment_free(stream->segment);
pthread_cond_destroy(&pin->event_cond); @@ -2517,11 +2524,11 @@ static struct parser_source *create_pin(struct parser *filter, const WCHAR *name pin->flushing_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": pin.flushing_cs");
sprintf(pad_name, "qz_sink_%u", filter->source_count); - pin->my_sink = gst_pad_new(pad_name, GST_PAD_SINK); - gst_pad_set_element_private(pin->my_sink, pin); - gst_pad_set_chain_function(pin->my_sink, got_data_sink); - gst_pad_set_event_function(pin->my_sink, event_sink); - gst_pad_set_query_function(pin->my_sink, query_sink_wrapper); + stream->my_sink = gst_pad_new(pad_name, GST_PAD_SINK); + gst_pad_set_element_private(stream->my_sink, pin); + gst_pad_set_chain_function(stream->my_sink, got_data_sink); + gst_pad_set_event_function(stream->my_sink, event_sink); + gst_pad_set_query_function(stream->my_sink, query_sink_wrapper);
filter->sources[filter->source_count++] = pin; return pin; @@ -2631,6 +2638,7 @@ static BOOL wave_parser_init_gst(struct parser *filter) { static const WCHAR source_name[] = {'o','u','t','p','u','t',0}; struct wg_parser *parser = filter->wg_parser; + struct wg_parser_stream *stream; struct parser_source *pin; GstElement *element; int ret; @@ -2653,15 +2661,16 @@ static BOOL wave_parser_init_gst(struct parser *filter)
if (!(pin = create_pin(filter, source_name))) return FALSE; - pin->their_src = gst_element_get_static_pad(element, "src"); - gst_object_ref(pin->their_src); - if ((ret = gst_pad_link(pin->their_src, pin->my_sink)) < 0) + stream = pin->wg_stream; + stream->their_src = gst_element_get_static_pad(element, "src"); + gst_object_ref(stream->their_src); + if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0) { ERR("Failed to link source pads, error %d.\n", ret); return FALSE; }
- gst_pad_set_active(pin->my_sink, 1); + gst_pad_set_active(stream->my_sink, 1); gst_element_set_state(parser->container, GST_STATE_PAUSED); ret = gst_element_get_state(parser->container, NULL, NULL, -1); if (ret == GST_STATE_CHANGE_FAILURE) @@ -2867,6 +2876,7 @@ static BOOL mpeg_splitter_init_gst(struct parser *filter) { static const WCHAR source_name[] = {'A','u','d','i','o',0}; struct wg_parser *parser = filter->wg_parser; + struct wg_parser_stream *stream; struct parser_source *pin; GstElement *element; int ret; @@ -2889,14 +2899,15 @@ static BOOL mpeg_splitter_init_gst(struct parser *filter)
if (!(pin = create_pin(filter, source_name))) return FALSE; - gst_object_ref(pin->their_src = gst_element_get_static_pad(element, "src")); - if ((ret = gst_pad_link(pin->their_src, pin->my_sink)) < 0) + stream = pin->wg_stream; + gst_object_ref(stream->their_src = gst_element_get_static_pad(element, "src")); + if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0) { ERR("Failed to link source pads, error %d.\n", ret); return FALSE; }
- gst_pad_set_active(pin->my_sink, 1); + gst_pad_set_active(stream->my_sink, 1); gst_element_set_state(parser->container, GST_STATE_PAUSED); ret = gst_element_get_state(parser->container, NULL, NULL, -1); if (ret == GST_STATE_CHANGE_FAILURE)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 5277a9fa3b9..728977f2bb5 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -77,6 +77,7 @@ struct wg_parser struct wg_parser_stream { GstPad *their_src, *post_sink, *post_src, *my_sink; + GstElement *flip; GstSegment *segment; };
@@ -139,7 +140,6 @@ struct parser_source
struct wg_parser_stream *wg_stream;
- GstElement *flip; GstCaps *caps; SourceSeeking seek;
@@ -1335,7 +1335,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct parser *Th
stream->post_sink = gst_element_get_static_pad(deinterlace, "sink"); stream->post_src = gst_element_get_static_pad(vconv2, "src"); - pin->flip = flip; + stream->flip = flip; } else if (!strcmp(typename, "audio/x-raw")) { @@ -2417,7 +2417,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pin->pin.pin.mt.pbFormat; buffer_size = format->bmiHeader.biSizeImage;
- gst_util_set_object_arg(G_OBJECT(pin->flip), "method", + gst_util_set_object_arg(G_OBJECT(stream->flip), "method", (format->bmiHeader.biCompression == BI_RGB || format->bmiHeader.biCompression == BI_BITFIELDS) ? "vertical-flip" : "none"); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 728977f2bb5..8d08ff370f4 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -79,6 +79,7 @@ struct wg_parser_stream GstPad *their_src, *post_sink, *post_src, *my_sink; GstElement *flip; GstSegment *segment; + GstCaps *caps; };
struct parser @@ -140,7 +141,6 @@ struct parser_source
struct wg_parser_stream *wg_stream;
- GstCaps *caps; SourceSeeking seek;
CRITICAL_SECTION flushing_cs; @@ -829,7 +829,7 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event)
gst_event_parse_caps(event, &caps); pthread_mutex_lock(&parser->mutex); - gst_caps_replace(&pin->caps, caps); + gst_caps_replace(&stream->caps, caps); pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->init_cond); break; @@ -1638,7 +1638,7 @@ static HRESULT GST_Connect(struct parser *This, IPin *pConnectPin)
pin->seek.llDuration = pin->seek.llStop = query_duration(stream->their_src); pin->seek.llCurrent = 0; - while (!pin->caps && !parser->error) + while (!stream->caps && !parser->error) pthread_cond_wait(&parser->init_cond, &parser->mutex); if (parser->error) { @@ -1932,7 +1932,8 @@ static HRESULT decodebin_parser_source_query_accept(struct parser_source *pin, c static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin, unsigned int index, AM_MEDIA_TYPE *mt) { - const GstCaps *caps = pin->caps; + struct wg_parser_stream *stream = pin->wg_stream; + const GstCaps *caps = stream->caps; const GstStructure *structure; const char *type;
@@ -2684,10 +2685,11 @@ static BOOL wave_parser_init_gst(struct parser *filter)
static HRESULT wave_parser_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; AM_MEDIA_TYPE pad_mt; HRESULT hr;
- if (!amt_from_gst_caps(pin->caps, &pad_mt)) + if (!amt_from_gst_caps(stream->caps, &pad_mt)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; FreeMediaType(&pad_mt); @@ -2697,9 +2699,11 @@ static HRESULT wave_parser_source_query_accept(struct parser_source *pin, const static HRESULT wave_parser_source_get_media_type(struct parser_source *pin, unsigned int index, AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; + if (index > 0) return VFW_S_NO_MORE_ITEMS; - if (!amt_from_gst_caps(pin->caps, mt)) + if (!amt_from_gst_caps(stream->caps, mt)) return E_OUTOFMEMORY; return S_OK; } @@ -2802,10 +2806,11 @@ static BOOL avi_splitter_init_gst(struct parser *filter)
static HRESULT avi_splitter_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; AM_MEDIA_TYPE pad_mt; HRESULT hr;
- if (!amt_from_gst_caps(pin->caps, &pad_mt)) + if (!amt_from_gst_caps(stream->caps, &pad_mt)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; FreeMediaType(&pad_mt); @@ -2815,9 +2820,11 @@ static HRESULT avi_splitter_source_query_accept(struct parser_source *pin, const static HRESULT avi_splitter_source_get_media_type(struct parser_source *pin, unsigned int index, AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; + if (index > 0) return VFW_S_NO_MORE_ITEMS; - if (!amt_from_gst_caps(pin->caps, mt)) + if (!amt_from_gst_caps(stream->caps, mt)) return E_OUTOFMEMORY; return S_OK; } @@ -2930,10 +2937,11 @@ static BOOL mpeg_splitter_init_gst(struct parser *filter)
static HRESULT mpeg_splitter_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; AM_MEDIA_TYPE pad_mt; HRESULT hr;
- if (!amt_from_gst_caps(pin->caps, &pad_mt)) + if (!amt_from_gst_caps(stream->caps, &pad_mt)) return E_OUTOFMEMORY; hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE; FreeMediaType(&pad_mt); @@ -2943,9 +2951,11 @@ static HRESULT mpeg_splitter_source_query_accept(struct parser_source *pin, cons static HRESULT mpeg_splitter_source_get_media_type(struct parser_source *pin, unsigned int index, AM_MEDIA_TYPE *mt) { + struct wg_parser_stream *stream = pin->wg_stream; + if (index > 0) return VFW_S_NO_MORE_ITEMS; - if (!amt_from_gst_caps(pin->caps, mt)) + if (!amt_from_gst_caps(stream->caps, mt)) return E_OUTOFMEMORY; return S_OK; }