--- a/patches/gst-plugins-good-04-selector.diff Tue Mar 30 00:45:10 2010 +0000
+++ b/patches/gst-plugins-good-04-selector.diff Tue Mar 30 03:12:53 2010 +0000
@@ -1,9 +1,10 @@
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/Makefile.am 2008-12-16 15:09:01.090359516 +0800
-@@ -0,0 +1,23 @@
-+glib_enum_prefix = gst_selector
++++ gst-plugins-good-0.10.21/gst/selector/Makefile.am 2008-12-16 15:09:01.090359516 +0800
+@@ -0,0 +1,24 @@
++glib_gen_prefix = gst_selector
++glib_gen_basename = gstselector
+
-+include $(top_srcdir)/common/glib-gen.mak
++include $(top_srcdir)/common/gst-glib-gen.mak
+
+built_sources = gstselector-marshal.c
+built_headers = gstselector-marshal.h
@@ -25,8 +26,8 @@
+
+noinst_HEADERS = gstinputselector.h gstoutputselector.h
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstinputselector.c 2008-12-16 15:09:01.091207753 +0800
-@@ -0,0 +1,1430 @@
++++ gst-plugins-good-0.10.21/gst/selector/gstinputselector.c 2008-12-16 15:09:01.091207753 +0800
+@@ -0,0 +1,1455 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <[email protected]>
+ * Copyright (C) 2005 Ronald S. Bultje <[email protected]>
@@ -75,7 +76,6 @@
+ "Generic",
+ "N-to-1 input stream selectoring",
+ "Julien Moutte <[email protected]>\n"
-+ "Ronald S. Bultje <[email protected]>\n"
+ "Jan Schmidt <[email protected]>\n"
+ "Wim Taymans <[email protected]>");
+
@@ -121,8 +121,8 @@
+};
+static guint gst_input_selector_signals[LAST_SIGNAL] = { 0 };
+
-+static gboolean gst_input_selector_is_active_sinkpad (GstInputSelector * sel,
-+ GstPad * pad);
++static inline gboolean gst_input_selector_is_active_sinkpad (GstInputSelector *
++ sel, GstPad * pad);
+static GstPad *gst_input_selector_activate_sinkpad (GstInputSelector * sel,
+ GstPad * pad);
+static GstPad *gst_input_selector_get_linked_pad (GstPad * pad,
@@ -178,7 +178,8 @@
+static void gst_selector_pad_reset (GstSelectorPad * pad);
+static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event);
+static GstCaps *gst_selector_pad_getcaps (GstPad * pad);
-+static GList *gst_selector_pad_get_linked_pads (GstPad * pad);
++static gboolean gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps);
++static GstIterator *gst_selector_pad_iterate_linked_pads (GstPad * pad);
+static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
+static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad,
+ guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
@@ -219,10 +220,8 @@
+
+ gobject_class->finalize = gst_selector_pad_finalize;
+
-+ gobject_class->get_property =
-+ GST_DEBUG_FUNCPTR (gst_selector_pad_get_property);
-+ gobject_class->set_property =
-+ GST_DEBUG_FUNCPTR (gst_selector_pad_set_property);
++ gobject_class->get_property = gst_selector_pad_get_property;
++ gobject_class->set_property = gst_selector_pad_set_property;
+
+ g_object_class_install_property (gobject_class, PROP_PAD_RUNNING_TIME,
+ g_param_spec_int64 ("running-time", "Running time",
@@ -349,19 +348,22 @@
+
+/* strictly get the linked pad from the sinkpad. If the pad is active we return
+ * the srcpad else we return NULL */
-+static GList *
-+gst_selector_pad_get_linked_pads (GstPad * pad)
++static GstIterator *
++gst_selector_pad_iterate_linked_pads (GstPad * pad)
+{
++ GstInputSelector *sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
+ GstPad *otherpad;
++ GstIterator *it;
+
+ otherpad = gst_input_selector_get_linked_pad (pad, TRUE);
-+ if (!otherpad)
-+ return NULL;
++ it = gst_iterator_new_single (GST_TYPE_PAD, otherpad,
++ (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
+
-+ /* need to drop the ref, internal linked pads is not MT safe */
-+ gst_object_unref (otherpad);
++ if (otherpad)
++ gst_object_unref (otherpad);
++ gst_object_unref (sel);
+
-+ return g_list_append (NULL, otherpad);
++ return it;
+}
+
+static gboolean
@@ -449,6 +451,8 @@
+ gst_tag_list_free (oldtags);
+ GST_DEBUG_OBJECT (pad, "received tags %" GST_PTR_FORMAT, newtags);
+ GST_OBJECT_UNLOCK (selpad);
++
++ g_object_notify (G_OBJECT (selpad), "tags");
+ break;
+ }
+ case GST_EVENT_EOS:
@@ -491,6 +495,21 @@
+ return caps;
+}
+
++static gboolean
++gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps)
++{
++ GstInputSelector *sel;
++ gboolean res;
++
++ sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
++
++ GST_DEBUG_OBJECT (sel, "Checking acceptcaps of srcpad peer");
++ res = gst_pad_peer_accept_caps (sel->srcpad, caps);
++ gst_object_unref (sel);
++
++ return res;
++}
++
+static GstFlowReturn
+gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset,
+ guint size, GstCaps * caps, GstBuffer ** buf)
@@ -568,9 +587,10 @@
+ GstPad *active_sinkpad;
+ GstPad *prev_active_sinkpad;
+ GstSelectorPad *selpad;
-+ GstClockTime end_time, duration;
++ GstClockTime start_time;
+ GstSegment *seg;
+ GstEvent *close_event = NULL, *start_event = NULL;
++ GstCaps *caps;
+
+ sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
+ selpad = GST_SELECTOR_PAD_CAST (pad);
@@ -587,16 +607,16 @@
+ active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
+
+ /* update the segment on the srcpad */
-+ end_time = GST_BUFFER_TIMESTAMP (buf);
-+ if (GST_CLOCK_TIME_IS_VALID (end_time)) {
-+ duration = GST_BUFFER_DURATION (buf);
-+ if (GST_CLOCK_TIME_IS_VALID (duration))
-+ end_time += duration;
-+ GST_DEBUG_OBJECT (pad, "received end time %" GST_TIME_FORMAT,
-+ GST_TIME_ARGS (end_time));
++ start_time = GST_BUFFER_TIMESTAMP (buf);
++ if (GST_CLOCK_TIME_IS_VALID (start_time)) {
++ GST_DEBUG_OBJECT (pad, "received start time %" GST_TIME_FORMAT,
++ GST_TIME_ARGS (start_time));
++ if (GST_BUFFER_DURATION_IS_VALID (buf))
++ GST_DEBUG_OBJECT (pad, "received end time %" GST_TIME_FORMAT,
++ GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
+
+ GST_OBJECT_LOCK (pad);
-+ gst_segment_set_last_stop (seg, seg->format, end_time);
++ gst_segment_set_last_stop (seg, seg->format, start_time);
+ GST_OBJECT_UNLOCK (pad);
+ }
+
@@ -608,7 +628,7 @@
+ GstSegment *cseg = &sel->segment;
+
+ GST_DEBUG_OBJECT (sel,
-+ "pushing NEWSEGMENT update %d, rate %lf, applied rate %lf, "
++ "pushing close NEWSEGMENT update %d, rate %lf, applied rate %lf, "
+ "format %d, "
+ "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
+ G_GINT64_FORMAT, TRUE, cseg->rate, cseg->applied_rate, cseg->format,
@@ -623,7 +643,7 @@
+ /* if we have a pending segment, push it out now */
+ if (G_UNLIKELY (selpad->segment_pending)) {
+ GST_DEBUG_OBJECT (pad,
-+ "pushing NEWSEGMENT update %d, rate %lf, applied rate %lf, "
++ "pushing pending NEWSEGMENT update %d, rate %lf, applied rate %lf, "
+ "format %d, "
+ "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
+ G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format,
@@ -657,6 +677,11 @@
+ GST_DEBUG_OBJECT (pad, "Forwarding buffer %p from pad %s:%s", buf,
+ GST_DEBUG_PAD_NAME (pad));
+
++ if ((caps = GST_BUFFER_CAPS (buf))) {
++ if (GST_PAD_CAPS (sel->srcpad) != caps)
++ gst_pad_set_caps (sel->srcpad, caps);
++ }
++
+ res = gst_pad_push (sel->srcpad, buf);
+
+done:
@@ -768,10 +793,8 @@
+
+ gobject_class->dispose = gst_input_selector_dispose;
+
-+ gobject_class->set_property =
-+ GST_DEBUG_FUNCPTR (gst_input_selector_set_property);
-+ gobject_class->get_property =
-+ GST_DEBUG_FUNCPTR (gst_input_selector_get_property);
++ gobject_class->set_property = gst_input_selector_set_property;
++ gobject_class->get_property = gst_input_selector_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_N_PADS,
+ g_param_spec_uint ("n-pads", "Number of Pads",
@@ -863,8 +886,8 @@
+gst_input_selector_init (GstInputSelector * sel)
+{
+ sel->srcpad = gst_pad_new ("src", GST_PAD_SRC);
-+ gst_pad_set_internal_link_function (sel->srcpad,
-+ GST_DEBUG_FUNCPTR (gst_selector_pad_get_linked_pads));
++ gst_pad_set_iterate_internal_links_function (sel->srcpad,
++ GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
+ gst_pad_set_getcaps_function (sel->srcpad,
+ GST_DEBUG_FUNCPTR (gst_input_selector_getcaps));
+ gst_pad_set_query_function (sel->srcpad,
@@ -912,7 +935,10 @@
+static gint64
+gst_segment_get_timestamp (GstSegment * segment, gint64 running_time)
+{
-+ return (running_time - segment->accum) * segment->abs_rate + segment->start;
++ if (running_time <= segment->accum)
++ return segment->start;
++ else
++ return (running_time - segment->accum) * segment->abs_rate + segment->start;
+}
+
+static void
@@ -1209,14 +1235,11 @@
+}
+
+/* check if the pad is the active sinkpad */
-+static gboolean
++static inline gboolean
+gst_input_selector_is_active_sinkpad (GstInputSelector * sel, GstPad * pad)
+{
-+ GstSelectorPad *selpad;
+ gboolean res;
+
-+ selpad = GST_SELECTOR_PAD_CAST (pad);
-+
+ GST_INPUT_SELECTOR_LOCK (sel);
+ res = (pad == sel->active_sinkpad);
+ GST_INPUT_SELECTOR_UNLOCK (sel);
@@ -1273,10 +1296,12 @@
+ GST_DEBUG_FUNCPTR (gst_selector_pad_event));
+ gst_pad_set_getcaps_function (sinkpad,
+ GST_DEBUG_FUNCPTR (gst_selector_pad_getcaps));
++ gst_pad_set_acceptcaps_function (sinkpad,
++ GST_DEBUG_FUNCPTR (gst_selector_pad_acceptcaps));
+ gst_pad_set_chain_function (sinkpad,
+ GST_DEBUG_FUNCPTR (gst_selector_pad_chain));
-+ gst_pad_set_internal_link_function (sinkpad,
-+ GST_DEBUG_FUNCPTR (gst_selector_pad_get_linked_pads));
++ gst_pad_set_iterate_internal_links_function (sinkpad,
++ GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
+ gst_pad_set_bufferalloc_function (sinkpad,
+ GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc));
+
@@ -1444,6 +1469,7 @@
+ if (!pad->eos) {
+ done = TRUE;
+ }
++ gst_object_unref (pad);
+ break;
+ case GST_ITERATOR_RESYNC:
+ gst_iterator_resync (it);
@@ -1458,7 +1484,7 @@
+ return is_eos;
+}
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstinputselector.h 2008-12-16 15:09:01.086278737 +0800
++++ gst-plugins-good-0.10.21/gst/selector/gstinputselector.h 2008-12-16 15:09:01.086278737 +0800
@@ -0,0 +1,84 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <[email protected]>
@@ -1545,8 +1571,8 @@
+
+#endif /* __GST_INPUT_SELECTOR_H__ */
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstoutputselector.c 2008-12-16 15:09:01.089181384 +0800
-@@ -0,0 +1,461 @@
++++ gst-plugins-good-0.10.21/gst/selector/gstoutputselector.c 2008-12-16 15:09:01.089181384 +0800
+@@ -0,0 +1,510 @@
+/* GStreamer
+ * Copyright (C) 2008 Nokia Corporation. (contact <[email protected]>)
+ *
@@ -1568,7 +1594,7 @@
+
+/**
+ * SECTION:element-output-selector
-+ * @see_also: #GstTee, #GstInputSelector
++ * @see_also: #GstOutputSelector, #GstInputSelector
+ *
+ * Direct input stream to one out of N output pads.
+ */
@@ -1623,6 +1649,8 @@
+static void gst_output_selector_release_pad (GstElement * element,
+ GstPad * pad);
+static GstFlowReturn gst_output_selector_chain (GstPad * pad, GstBuffer * buf);
++static GstFlowReturn gst_output_selector_buffer_alloc (GstPad * pad,
++ guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+static GstStateChangeReturn gst_output_selector_change_state (GstElement *
+ element, GstStateChange transition);
+static gboolean gst_output_selector_handle_sink_event (GstPad * pad,
@@ -1685,21 +1713,21 @@
+ GST_DEBUG_FUNCPTR (gst_output_selector_chain));
+ gst_pad_set_event_function (sel->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_output_selector_handle_sink_event));
-+
-+ gst_element_add_pad (GST_ELEMENT (sel), sel->sinkpad);
-+
++ gst_pad_set_bufferalloc_function (sel->sinkpad,
++ GST_DEBUG_FUNCPTR (gst_output_selector_buffer_alloc));
+ /*
-+ gst_pad_set_bufferalloc_function (sel->sinkpad,
-+ GST_DEBUG_FUNCPTR (gst_output_selector_bufferalloc));
+ gst_pad_set_setcaps_function (sel->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps));
+ gst_pad_set_getcaps_function (sel->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
+ */
++
++ gst_element_add_pad (GST_ELEMENT (sel), sel->sinkpad);
++
+ /* srcpad management */
+ sel->active_srcpad = NULL;
+ sel->nb_srcpads = 0;
-+ gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
++ gst_segment_init (&sel->segment, GST_FORMAT_TIME);
+ sel->pending_srcpad = NULL;
+
+ sel->resend_latest = FALSE;
@@ -1743,7 +1771,7 @@
+
+ next_pad = g_value_get_object (value);
+
-+ GST_LOG_OBJECT (sel, "Activating pad %s:%s",
++ GST_INFO_OBJECT (sel, "Activating pad %s:%s",
+ GST_DEBUG_PAD_NAME (next_pad));
+
+ GST_OBJECT_LOCK (object);
@@ -1785,7 +1813,8 @@
+ switch (prop_id) {
+ case PROP_ACTIVE_PAD:
+ GST_OBJECT_LOCK (object);
-+ g_value_set_object (value, sel->active_srcpad);
++ g_value_set_object (value,
++ sel->pending_srcpad ? sel->pending_srcpad : sel->active_srcpad);
+ GST_OBJECT_UNLOCK (object);
+ break;
+ case PROP_RESEND_LATEST:{
@@ -1800,6 +1829,44 @@
+ }
+}
+
++static GstFlowReturn
++gst_output_selector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
++ GstCaps * caps, GstBuffer ** buf)
++{
++ GstOutputSelector *sel;
++ GstFlowReturn res;
++ GstPad *allocpad;
++
++ sel = GST_OUTPUT_SELECTOR (GST_PAD_PARENT (pad));
++ res = GST_FLOW_NOT_LINKED;
++
++ GST_OBJECT_LOCK (sel);
++ allocpad = sel->pending_srcpad ? sel->pending_srcpad : sel->active_srcpad;
++ if (allocpad) {
++ /* if we had a previous pad we used for allocating a buffer, continue using
++ * it. */
++ GST_DEBUG_OBJECT (sel, "using pad %s:%s for alloc",
++ GST_DEBUG_PAD_NAME (allocpad));
++ gst_object_ref (allocpad);
++ GST_OBJECT_UNLOCK (sel);
++
++ res = gst_pad_alloc_buffer (allocpad, offset, size, caps, buf);
++ gst_object_unref (allocpad);
++
++ GST_OBJECT_LOCK (sel);
++ } else {
++ /* fallback case, allocate a buffer of our own, add pad caps. */
++ GST_DEBUG_OBJECT (pad, "fallback buffer alloc");
++ *buf = NULL;
++ res = GST_FLOW_OK;
++ }
++ GST_OBJECT_UNLOCK (sel);
++
++ GST_DEBUG_OBJECT (sel, "buffer alloc finished: %s", gst_flow_get_name (res));
++
++ return res;
++}
++
+static GstPad *
+gst_output_selector_request_new_pad (GstElement * element,
+ GstPadTemplate * templ, const gchar * name)
@@ -1846,14 +1913,24 @@
+static gboolean
+gst_output_selector_switch (GstOutputSelector * osel)
+{
-+ gboolean res = TRUE;
++ gboolean res = FALSE;
+ GstEvent *ev = NULL;
+ GstSegment *seg = NULL;
+ gint64 start = 0, position = 0;
+
++ /* Switch */
++ GST_OBJECT_LOCK (GST_OBJECT (osel));
+ GST_INFO ("switching to pad %" GST_PTR_FORMAT, osel->pending_srcpad);
++ if (gst_pad_is_linked (osel->pending_srcpad)) {
++ osel->active_srcpad = osel->pending_srcpad;
++ res = TRUE;
++ }
++ gst_object_unref (osel->pending_srcpad);
++ osel->pending_srcpad = NULL;
++ GST_OBJECT_UNLOCK (GST_OBJECT (osel));
+
-+ if (gst_pad_is_linked (osel->pending_srcpad)) {
++ /* Send NEWSEGMENT event and latest buffer if switching succeeded */
++ if (res) {
+ /* Send NEWSEGMENT to the pad we are going to switch to */
+ seg = &osel->segment;
+ /* If resending then mark newsegment start and position accordingly */
@@ -1865,29 +1942,22 @@
+ }
+ ev = gst_event_new_new_segment (TRUE, seg->rate,
+ seg->format, start, seg->stop, position);
-+ if (!gst_pad_push_event (osel->pending_srcpad, ev)) {
++ if (!gst_pad_push_event (osel->active_srcpad, ev)) {
+ GST_WARNING_OBJECT (osel,
+ "newsegment handling failed in %" GST_PTR_FORMAT,
-+ osel->pending_srcpad);
++ osel->active_srcpad);
+ }
+
+ /* Resend latest buffer to newly switched pad */
+ if (osel->resend_latest && osel->latest_buffer) {
+ GST_INFO ("resending latest buffer");
-+ gst_pad_push (osel->pending_srcpad, osel->latest_buffer);
++ gst_pad_push (osel->active_srcpad, osel->latest_buffer);
+ osel->latest_buffer = NULL;
+ }
-+
-+ /* Switch */
-+ osel->active_srcpad = osel->pending_srcpad;
+ } else {
+ GST_WARNING_OBJECT (osel, "switch failed, pad not linked");
-+ res = FALSE;
+ }
+
-+ gst_object_unref (osel->pending_srcpad);
-+ osel->pending_srcpad = NULL;
-+
+ return res;
+}
+
@@ -1905,10 +1975,15 @@
+ gst_output_selector_switch (osel);
+ }
+
-+ /* Keep reference to latest buffer to resend it after switch */
-+ if (osel->latest_buffer)
++ if (osel->latest_buffer) {
+ gst_buffer_unref (osel->latest_buffer);
-+ osel->latest_buffer = gst_buffer_ref (buf);
++ osel->latest_buffer = NULL;
++ }
++
++ if (osel->resend_latest) {
++ /* Keep reference to latest buffer to resend it after switch */
++ osel->latest_buffer = gst_buffer_ref (buf);
++ }
+
+ /* Keep track of last stop and use it in NEWSEGMENT start after
+ switching to a new src pad */
@@ -2009,7 +2084,7 @@
+ return res;
+}
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstoutputselector.h 2008-12-16 15:09:01.073579304 +0800
++++ gst-plugins-good-0.10.21/gst/selector/gstoutputselector.h 2008-12-16 15:09:01.073579304 +0800
@@ -0,0 +1,66 @@
+/* GStreamer
+ * Copyright (C) 2008 Nokia Corporation. (contact <[email protected]>)
@@ -2078,7 +2153,7 @@
+
+#endif /* __GST_OUTPUT_SELECTOR_H__ */
--- /dev/null 2008-12-16 15:34:15.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstselector.c 2008-12-16 15:09:01.090104873 +0800
++++ gst-plugins-good-0.10.21/gst/selector/gstselector.c 2008-12-16 15:09:01.090104873 +0800
@@ -0,0 +1,44 @@
+/* GStreamer
+ * Copyright (C) 2008 Nokia Corporation. (contact <[email protected]>)
@@ -2125,7 +2200,7 @@
+ "input/output stream selector elements",
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
--- /dev/null 2008-12-20 18:00:51.000000000 +0800
-+++ gst-plugins-good-0.10.11/gst/selector/gstselector-marshal.list 2008-12-16 15:09:01.089768915 +0800
++++ gst-plugins-good-0.10.21/gst/selector/gstselector-marshal.list 2008-12-16 15:09:01.089768915 +0800
@@ -0,0 +1,2 @@
+INT64:VOID
+VOID:OBJECT,INT64,INT64