From: Charlotte Pabst cpabst@codeweavers.com
--- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/main.c | 12 +++++++ dlls/winegstreamer/unixlib.h | 8 +++++ dlls/winegstreamer/wg_parser.c | 54 ++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 60e0c3af8bc..2d5986fdb1b 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -81,6 +81,8 @@ void wg_parser_disconnect(wg_parser_t parser); bool wg_parser_get_next_read_offset(wg_parser_t parser, uint64_t *offset, uint32_t *size); void wg_parser_push_data(wg_parser_t parser, const void *data, uint32_t size);
+void wg_parser_set_thinning(wg_parser_t parser, BOOL thinning); + uint32_t wg_parser_get_stream_count(wg_parser_t parser); wg_parser_stream_t wg_parser_get_stream(wg_parser_t parser, uint32_t index);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index d18db8b21e8..c68cf0c04f1 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -240,6 +240,18 @@ void wg_parser_push_data(wg_parser_t parser, const void *data, uint32_t size) WINE_UNIX_CALL(unix_wg_parser_push_data, ¶ms); }
+void wg_parser_set_thinning(wg_parser_t parser, BOOL thinning) +{ + struct wg_parser_set_thinning_params params = + { + .parser = parser, + .thinning = thinning, + }; + TRACE("parser %#I64x, thinning %d.\n", parser, thinning); + + WINE_UNIX_CALL(unix_wg_parser_set_thinning, ¶ms); +} + uint32_t wg_parser_get_stream_count(wg_parser_t parser) { struct wg_parser_get_stream_count_params params = diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 83e38849fa9..1df26360aca 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -245,6 +245,12 @@ struct wg_parser_push_data_params UINT32 size; };
+struct wg_parser_set_thinning_params +{ + wg_parser_t parser; + BOOL thinning; +}; + struct wg_parser_get_stream_count_params { wg_parser_t parser; @@ -429,6 +435,8 @@ enum unix_funcs unix_wg_parser_get_next_read_offset, unix_wg_parser_push_data,
+ unix_wg_parser_set_thinning, + unix_wg_parser_get_stream_count, unix_wg_parser_get_stream,
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index e806298fb57..dd1812d2d0e 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -80,6 +80,7 @@ struct wg_parser bool output_compressed; bool no_more_pads, has_duration, error; bool err_on, warn_on; + bool thinning;
pthread_cond_t read_cond, read_done_cond; struct @@ -226,6 +227,19 @@ static NTSTATUS wg_parser_push_data(void *args) return S_OK; }
+static NTSTATUS wg_parser_set_thinning(void *args) +{ + const struct wg_parser_set_thinning_params *params = args; + struct wg_parser *parser = get_parser(params->parser); + BOOL thinning = params->thinning; + + pthread_mutex_lock(&parser->mutex); + parser->thinning = thinning; + pthread_mutex_unlock(&parser->mutex); + + return S_OK; +} + static NTSTATUS wg_parser_stream_get_current_format(void *args) { const struct wg_parser_stream_get_current_format_params *params = args; @@ -600,10 +614,46 @@ static void no_more_pads_cb(GstElement *element, gpointer user) pthread_cond_signal(&parser->init_cond); }
+static GstPadProbeReturn decoder_pad_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user) +{ + struct wg_parser *parser = user; + GstBuffer *buffer; + bool thinning; + + pthread_mutex_lock(&parser->mutex); + thinning = parser->thinning; + pthread_mutex_unlock(&parser->mutex); + + if (thinning && (buffer = gst_pad_probe_info_get_buffer(info))) + { + if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) + { + GST_DEBUG("Stream is thinned; discarding delta frame."); + return GST_PAD_PROBE_DROP; + } + else + { + GST_DEBUG("Stream is thinned; found key frame."); + } + } + + return GST_PAD_PROBE_OK; +} + static void deep_element_added_cb(GstBin *self, GstBin *sub_bin, GstElement *element, gpointer user) { + struct wg_parser *parser = user; + if (element) + { + GstElementFactory *fact = GST_ELEMENT_GET_CLASS(element)->elementfactory; + const char *klass = gst_element_factory_get_klass(fact); + GstPad *sink; + if (strstr(klass, GST_ELEMENT_FACTORY_KLASS_DECODER) && (sink = gst_element_get_static_pad(element, "sink"))) + gst_pad_add_probe(sink, GST_PAD_PROBE_TYPE_BUFFER, decoder_pad_probe, parser, NULL); + set_max_threads(element); + } }
static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) @@ -1911,6 +1961,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_parser_get_next_read_offset), X(wg_parser_push_data),
+ X(wg_parser_set_thinning), + X(wg_parser_get_stream_count), X(wg_parser_get_stream),
@@ -2308,6 +2360,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X(wg_parser_get_next_read_offset), X64(wg_parser_push_data),
+ X(wg_parser_set_thinning), + X(wg_parser_get_stream_count), X(wg_parser_get_stream),