diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-05-21 11:12:23 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-05-21 11:12:23 +0200 |
commit | 50f12103f5a136f45bd274ac6a99006a3db5ca4d (patch) | |
tree | cb44f58b9f1cc9256a83b87d28d6cdaf10b2c4b4 /plugins | |
parent | 54399760aad93cb3ec36162ced7649c8cd8286db (diff) |
Imported Upstream version 0.11.91upstream/0.11.91
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.in | 2 | ||||
-rw-r--r-- | plugins/elements/Makefile.in | 4 | ||||
-rw-r--r-- | plugins/elements/gstfilesrc.c | 4 | ||||
-rw-r--r-- | plugins/elements/gstinputselector.c | 77 | ||||
-rw-r--r-- | plugins/elements/gstmultiqueue.c | 1 | ||||
-rw-r--r-- | plugins/elements/gsttee.c | 104 |
6 files changed, 108 insertions, 84 deletions
diff --git a/plugins/Makefile.in b/plugins/Makefile.in index 539c2ed..4d019da 100644 --- a/plugins/Makefile.in +++ b/plugins/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.4 from Makefile.am. +# Makefile.in generated by automake 1.11.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/plugins/elements/Makefile.in b/plugins/elements/Makefile.in index 2cc34f1..15c6d3d 100644 --- a/plugins/elements/Makefile.in +++ b/plugins/elements/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.4 from Makefile.am. +# Makefile.in generated by automake 1.11.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -555,7 +555,7 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ - $(MKDIR_P) '$(DESTDIR)$(plugindir)' || exit 1; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 8f55d1f..8536f4a 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -42,11 +42,14 @@ #include <stdio.h> #include <sys/types.h> +#include <sys/stat.h> #ifdef G_OS_WIN32 #include <io.h> /* lseek, open, close, read */ /* On win32, stat* default to 32 bit; we need the 64-bit * variants, so explicitly define it that way. */ +#undef stat #define stat __stat64 +#undef fstat #define fstat _fstat64 #undef lseek #define lseek _lseeki64 @@ -56,7 +59,6 @@ * _stat*, since we're explicitly overriding that */ #undef _INC_STAT_INL #endif -#include <sys/stat.h> #include <fcntl.h> #ifdef HAVE_UNISTD_H diff --git a/plugins/elements/gstinputselector.c b/plugins/elements/gstinputselector.c index 564e721..eb6fba5 100644 --- a/plugins/elements/gstinputselector.c +++ b/plugins/elements/gstinputselector.c @@ -146,7 +146,7 @@ struct _GstSelectorPad GstSegment segment; /* the current segment on the pad */ guint32 segment_seqnum; /* sequence number of the current segment */ - gboolean segment_pending; + gboolean events_pending; /* TRUE if sticky events need to be updated */ }; struct _GstSelectorPadClass @@ -307,7 +307,7 @@ gst_selector_pad_reset (GstSelectorPad * pad) pad->pushed = FALSE; pad->eos = FALSE; pad->eos_sent = FALSE; - pad->segment_pending = FALSE; + pad->events_pending = FALSE; pad->discont = FALSE; pad->flushing = FALSE; pad->position = GST_CLOCK_TIME_NONE; @@ -401,15 +401,6 @@ gst_selector_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) GST_DEBUG_OBJECT (pad, "configured SEGMENT %" GST_SEGMENT_FORMAT, &selpad->segment); - /* If we aren't forwarding the event because the pad is not the - * active_sinkpad, then set the flag on the pad - * that says a segment needs sending if/when that pad is activated. - * For all other cases, we send the event immediately, which makes - * sparse streams and other segment updates work correctly downstream. - */ - if (!forward) - selpad->segment_pending = TRUE; - GST_OBJECT_UNLOCK (selpad); GST_INPUT_SELECTOR_UNLOCK (sel); break; @@ -462,8 +453,17 @@ gst_selector_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) if (forward) { GST_DEBUG_OBJECT (pad, "forwarding event"); res = gst_pad_push_event (sel->srcpad, event); - } else + } else { + /* If we aren't forwarding the event because the pad is not the + * active_sinkpad, then set the flag on the pad + * that says a segment needs sending if/when that pad is activated. + * For all other cases, we send the event immediately, which makes + * sparse streams and other segment updates work correctly downstream. + */ + if (GST_EVENT_IS_STICKY (event)) + selpad->events_pending = TRUE; gst_event_unref (event); + } return res; } @@ -594,6 +594,25 @@ gst_input_selector_wait_running_time (GstInputSelector * sel, return (sel->flushing || pad->flushing); } +static gboolean +forward_sticky_events (GstPad * sinkpad, GstEvent ** event, gpointer user_data) +{ + GstInputSelector *sel = GST_INPUT_SELECTOR (user_data); + + if (GST_EVENT_TYPE (*event) == GST_EVENT_SEGMENT) { + GstSegment *seg = &GST_SELECTOR_PAD (sinkpad)->segment; + GstEvent *e; + + e = gst_event_new_segment (seg); + gst_event_set_seqnum (e, GST_SELECTOR_PAD_CAST (sinkpad)->segment_seqnum); + + gst_pad_push_event (sel->srcpad, e); + } else { + gst_pad_push_event (sel->srcpad, gst_event_ref (*event)); + } + + return TRUE; +} static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) @@ -604,12 +623,9 @@ gst_selector_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) GstPad *prev_active_sinkpad; GstSelectorPad *selpad; GstClockTime start_time; - GstSegment *seg; - GstEvent *start_event = NULL; sel = GST_INPUT_SELECTOR (parent); selpad = GST_SELECTOR_PAD_CAST (pad); - seg = &selpad->segment; GST_INPUT_SELECTOR_LOCK (sel); /* wait or check for flushing */ @@ -642,6 +658,7 @@ gst_selector_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) GST_OBJECT_LOCK (pad); selpad->position = start_time; + selpad->segment.position = start_time; GST_OBJECT_UNLOCK (pad); } @@ -653,31 +670,19 @@ gst_selector_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) if (sel->sync_streams) GST_INPUT_SELECTOR_BROADCAST (sel); - /* if we have a pending segment, push it out now */ - if (G_UNLIKELY (prev_active_sinkpad != active_sinkpad - || selpad->segment_pending)) { - if (G_UNLIKELY (seg->format == GST_FORMAT_UNDEFINED)) { - GST_ERROR_OBJECT (pad, "Buffers arrived before NEWSEGMENT event"); - } else { - GST_DEBUG_OBJECT (pad, - "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, - seg->start, seg->stop, seg->time); - - start_event = gst_event_new_segment (seg); - gst_event_set_seqnum (start_event, selpad->segment_seqnum); - selpad->segment_pending = FALSE; - } - } GST_INPUT_SELECTOR_UNLOCK (sel); if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad) { g_object_notify (G_OBJECT (sel), "active-pad"); } - if (start_event) - gst_pad_push_event (sel->srcpad, start_event); + /* if we have a pending events, push them now */ + if (G_UNLIKELY (prev_active_sinkpad != active_sinkpad + || selpad->events_pending)) { + gst_pad_sticky_events_foreach (GST_PAD_CAST (selpad), forward_sticky_events, + sel); + selpad->events_pending = FALSE; + } if (selpad->discont) { buf = gst_buffer_make_writable (buf); @@ -924,11 +929,13 @@ gst_input_selector_set_active_pad (GstInputSelector * self, GstPad * pad) /* Send a new SEGMENT event on the new pad next */ if (old != new && new) - new->segment_pending = TRUE; + new->events_pending = TRUE; active_pad_p = &self->active_sinkpad; gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad)); + gst_pad_push_event (pad, gst_event_new_reconfigure ()); + /* Wake up all non-active pads in sync mode, they might be * the active pad now */ if (self->sync_streams) diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index 09db153..bd3b69c 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -755,7 +755,6 @@ gst_single_queue_flush (GstMultiQueue * mq, GstSingleQueue * sq, gboolean flush) gst_data_queue_set_flushing (sq->queue, TRUE); sq->flushing = TRUE; - GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); /* wake up non-linked task */ GST_LOG_OBJECT (mq, "SingleQueue %d : waking up eventually waiting task", diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 3cae773..33f2d8d 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -107,24 +107,66 @@ GST_STATIC_PAD_TEMPLATE ("src_%u", GST_PAD_REQUEST, GST_STATIC_CAPS_ANY); -/* structure and quark to keep track of which pads have been pushed */ -static GQuark push_data; - #define _do_init \ - GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element"); \ - push_data = g_quark_from_static_string ("tee-push-data"); + GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element"); #define gst_tee_parent_class parent_class G_DEFINE_TYPE_WITH_CODE (GstTee, gst_tee, GST_TYPE_ELEMENT, _do_init); static GParamSpec *pspec_last_message = NULL; static GParamSpec *pspec_alloc_pad = NULL; -typedef struct +GType gst_tee_pad_get_type (void); + +#define GST_TYPE_TEE_PAD \ + (gst_tee_pad_get_type()) +#define GST_TEE_PAD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEE_PAD, GstTeePad)) +#define GST_TEE_PAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEE_PAD, GstTeePadClass)) +#define GST_IS_TEE_PAD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEE_PAD)) +#define GST_IS_TEE_PAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEE_PAD)) +#define GST_TEE_PAD_CAST(obj) \ + ((GstTeePad *)(obj)) + +typedef struct _GstTeePad GstTeePad; +typedef struct _GstTeePadClass GstTeePadClass; + +struct _GstTeePad { + GstPad parent; + gboolean pushed; GstFlowReturn result; gboolean removed; -} PushData; +}; + +struct _GstTeePadClass +{ + GstPadClass parent; +}; + +G_DEFINE_TYPE (GstTeePad, gst_tee_pad, GST_TYPE_PAD); + +static void +gst_tee_pad_class_init (GstTeePadClass * klass) +{ +} + +static void +gst_tee_pad_reset (GstTeePad * pad) +{ + pad->pushed = FALSE; + pad->result = GST_FLOW_NOT_LINKED; + pad->removed = FALSE; +} + +static void +gst_tee_pad_init (GstTeePad * pad) +{ + gst_tee_pad_reset (pad); +} static GstPad *gst_tee_request_new_pad (GstElement * element, GstPadTemplate * temp, const gchar * unused, const GstCaps * caps); @@ -295,7 +337,6 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, GstTee *tee; GstPadMode mode; gboolean res; - PushData *data; tee = GST_TEE (element); @@ -304,19 +345,13 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, GST_OBJECT_LOCK (tee); name = g_strdup_printf ("src_%u", tee->pad_counter++); - srcpad = gst_pad_new_from_template (templ, name); + srcpad = GST_PAD_CAST (g_object_new (GST_TYPE_TEE_PAD, + "name", name, "direction", templ->direction, "template", templ, + NULL)); g_free (name); mode = tee->sink_mode; - /* install the data, we automatically free it when the pad is disposed because - * of _release_pad or when the element goes away. */ - data = g_new0 (PushData, 1); - data->pushed = FALSE; - data->result = GST_FLOW_NOT_LINKED; - data->removed = FALSE; - g_object_set_qdata_full (G_OBJECT (srcpad), push_data, data, g_free); - GST_OBJECT_UNLOCK (tee); switch (mode) { @@ -370,7 +405,6 @@ static void gst_tee_release_pad (GstElement * element, GstPad * pad) { GstTee *tee; - PushData *data; gboolean changed = FALSE; tee = GST_TEE (element); @@ -379,11 +413,9 @@ gst_tee_release_pad (GstElement * element, GstPad * pad) /* wait for pending pad_alloc to finish */ GST_TEE_DYN_LOCK (tee); - data = g_object_get_qdata (G_OBJECT (pad), push_data); - GST_OBJECT_LOCK (tee); /* mark the pad as removed so that future pad_alloc fails with NOT_LINKED. */ - data->removed = TRUE; + GST_TEE_PAD_CAST (pad)->removed = TRUE; if (tee->allocpad == pad) { tee->allocpad = NULL; changed = TRUE; @@ -550,15 +582,8 @@ gst_tee_do_push (GstTee * tee, GstPad * pad, gpointer data, gboolean is_list) static void clear_pads (GstPad * pad, GstTee * tee) { - PushData *data; - - data = g_object_get_qdata ((GObject *) pad, push_data); - - /* the data must be there or we have a screwed up internal state */ - g_assert (data != NULL); - - data->pushed = FALSE; - data->result = GST_FLOW_NOT_LINKED; + GST_TEE_PAD_CAST (pad)->pushed = FALSE; + GST_TEE_PAD_CAST (pad)->result = GST_FLOW_NOT_LINKED; } static GstFlowReturn @@ -604,16 +629,10 @@ restart: while (pads) { GstPad *pad; - PushData *pdata; pad = GST_PAD_CAST (pads->data); - /* get the private data, something is really wrong with the internal state - * when it is not there */ - pdata = g_object_get_qdata ((GObject *) pad, push_data); - g_assert (pdata != NULL); - - if (G_LIKELY (!pdata->pushed)) { + if (G_LIKELY (!GST_TEE_PAD_CAST (pad)->pushed)) { /* not yet pushed, release lock and start pushing */ gst_object_ref (pad); GST_OBJECT_UNLOCK (tee); @@ -627,15 +646,13 @@ restart: gst_flow_get_name (ret)); GST_OBJECT_LOCK (tee); - /* keep track of which pad we pushed and the result value. We need to do - * this before we release the refcount on the pad, the PushData is - * destroyed when the last ref of the pad goes away. */ - pdata->pushed = TRUE; - pdata->result = ret; + /* keep track of which pad we pushed and the result value */ + GST_TEE_PAD_CAST (pad)->pushed = TRUE; + GST_TEE_PAD_CAST (pad)->result = ret; gst_object_unref (pad); } else { /* already pushed, use previous return value */ - ret = pdata->result; + ret = GST_TEE_PAD_CAST (pad)->result; GST_LOG_OBJECT (tee, "pad already pushed with %s", gst_flow_get_name (ret)); } @@ -803,7 +820,6 @@ gst_tee_src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, res = TRUE; break; } - GST_OBJECT_UNLOCK (tee); return res; |