aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-05-21 11:12:23 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-05-21 11:12:23 +0200
commit50f12103f5a136f45bd274ac6a99006a3db5ca4d (patch)
treecb44f58b9f1cc9256a83b87d28d6cdaf10b2c4b4 /plugins
parent54399760aad93cb3ec36162ced7649c8cd8286db (diff)
Imported Upstream version 0.11.91upstream/0.11.91
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.in2
-rw-r--r--plugins/elements/Makefile.in4
-rw-r--r--plugins/elements/gstfilesrc.c4
-rw-r--r--plugins/elements/gstinputselector.c77
-rw-r--r--plugins/elements/gstmultiqueue.c1
-rw-r--r--plugins/elements/gsttee.c104
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;