From: Wim Taymans Date: Wed, 27 Aug 2008 15:45:16 +0000 (+0000) Subject: plugins/elements/gstinputselector.c: Implement the LATENCY query in a better way... X-Git-Tag: RELEASE-0.10.32~113 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a7cd6eeb615da7948382f0aba25fa1191e82e6d3;p=platform%2Fupstream%2Fgstreamer.git plugins/elements/gstinputselector.c: Implement the LATENCY query in a better way by taking the latency of all sinkpads an... Original commit message from CVS: * plugins/elements/gstinputselector.c: (gst_input_selector_init), (gst_input_selector_query): Implement the LATENCY query in a better way by taking the latency of all sinkpads and taking the min/max instead of just taking a random pad. --- diff --git a/plugins/elements/gstinputselector.c b/plugins/elements/gstinputselector.c index 4393ebf..2b557e0 100644 --- a/plugins/elements/gstinputselector.c +++ b/plugins/elements/gstinputselector.c @@ -658,6 +658,7 @@ static GstStateChangeReturn gst_input_selector_change_state (GstElement * static GList *gst_input_selector_get_linked_pads (GstPad * pad); static GstCaps *gst_input_selector_getcaps (GstPad * pad); +static gboolean gst_input_selector_query (GstPad * pad, GstQuery * query); static gint64 gst_input_selector_block (GstInputSelector * self); static void gst_input_selector_switch (GstInputSelector * self, GstPad * pad, gint64 stop_time, gint64 start_time); @@ -809,6 +810,8 @@ gst_input_selector_init (GstInputSelector * sel) GST_DEBUG_FUNCPTR (gst_input_selector_get_linked_pads)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_getcaps)); + gst_pad_set_query_function (sel->srcpad, + GST_DEBUG_FUNCPTR (gst_input_selector_query)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->active_sinkpad = NULL; @@ -1008,6 +1011,83 @@ gst_input_selector_get_linked_pad (GstPad * pad, gboolean strict) return otherpad; } +/* query on the srcpad. We override this function because by default it will + * only forward the query to one random sinkpad */ +static gboolean +gst_input_selector_query (GstPad * pad, GstQuery * query) +{ + gboolean res; + GstInputSelector *sel; + + sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_LATENCY: + { + GList *walk; + GstClockTime resmin, resmax; + gboolean reslive; + + resmin = 0; + resmax = -1; + reslive = FALSE; + + /* assume FALSE, we become TRUE if one query succeeds */ + res = FALSE; + + /* perform the query on all sinkpads and combine the results. We take the + * max of min and the min of max for the result latency. */ + GST_INPUT_SELECTOR_LOCK (sel); + for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk; + walk = g_list_next (walk)) { + GstPad *sinkpad = GST_PAD_CAST (walk->data); + + if (gst_pad_peer_query (sinkpad, query)) { + GstClockTime min, max; + gboolean live; + + /* one query succeeded, we succeed too */ + res = TRUE; + + gst_query_parse_latency (query, &live, &min, &max); + + GST_DEBUG_OBJECT (sinkpad, + "peer latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT + ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live); + + if (live) { + if (min > resmin) + resmin = min; + if (resmax == -1) + resmax = max; + else if (max < resmax) + resmax = max; + if (reslive == FALSE) + reslive = live; + } + } + } + GST_INPUT_SELECTOR_UNLOCK (sel); + if (res) { + gst_query_set_latency (query, reslive, resmin, resmax); + + GST_DEBUG_OBJECT (sel, + "total latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT + ", live %d", GST_TIME_ARGS (resmin), GST_TIME_ARGS (resmax), + reslive); + } + + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } + gst_object_unref (sel); + + return res; +} + static GstCaps * gst_input_selector_getcaps (GstPad * pad) {