mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
gst/switch/gstswitch.h (struct _GstStreamSelector): Add some state variables.
Original commit message from CVS: 2007-12-17 Andy Wingo <wingo@pobox.com> * gst/switch/gstswitch.h (struct _GstStreamSelector): Add some state variables. * gst/switch/gstswitch.c (gst_stream_selector_push_pending_stop) (gst_selector_pad_chain): Push any pending stop event. (gst_stream_selector_set_active_pad) (gst_stream_selector_set_property): Factor out setting the active pad to a function. Close the segment of the previous active pad if told to do so via a stop_time != GST_CLOCK_TIME_NONE. (gst_stream_selector_switch): Implement switch vmethod. Patch 5/12.
This commit is contained in:
parent
5d8d5eb81d
commit
7a36821856
3 changed files with 103 additions and 29 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,5 +1,16 @@
|
||||||
2007-12-17 Andy Wingo <wingo@pobox.com>
|
2007-12-17 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst/switch/gstswitch.h (struct _GstStreamSelector): Add some
|
||||||
|
state variables.
|
||||||
|
|
||||||
|
* gst/switch/gstswitch.c (gst_stream_selector_push_pending_stop)
|
||||||
|
(gst_selector_pad_chain): Push any pending stop event.
|
||||||
|
(gst_stream_selector_set_active_pad)
|
||||||
|
(gst_stream_selector_set_property): Factor out setting the active
|
||||||
|
pad to a function. Close the segment of the previous active pad if
|
||||||
|
told to do so via a stop_time != GST_CLOCK_TIME_NONE.
|
||||||
|
(gst_stream_selector_switch): Implement switch vmethod. Patch 5/12.
|
||||||
|
|
||||||
* gst/switch/gstswitch.c (gst_stream_selector_block): Implement
|
* gst/switch/gstswitch.c (gst_stream_selector_block): Implement
|
||||||
the block() signal. This implementation will be replaced in future
|
the block() signal. This implementation will be replaced in future
|
||||||
patches, however. Patch 4/12.
|
patches, however. Patch 4/12.
|
||||||
|
|
|
@ -73,6 +73,7 @@ static GstPad *gst_stream_selector_activate_sinkpad (GstStreamSelector * sel,
|
||||||
GstPad * pad);
|
GstPad * pad);
|
||||||
static GstPad *gst_stream_selector_get_linked_pad (GstPad * pad,
|
static GstPad *gst_stream_selector_get_linked_pad (GstPad * pad,
|
||||||
gboolean strict);
|
gboolean strict);
|
||||||
|
static void gst_stream_selector_push_pending_stop (GstStreamSelector * self);
|
||||||
|
|
||||||
#define GST_TYPE_SELECTOR_PAD \
|
#define GST_TYPE_SELECTOR_PAD \
|
||||||
(gst_selector_pad_get_type())
|
(gst_selector_pad_get_type())
|
||||||
|
@ -339,6 +340,8 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
|
||||||
if (pad != active_sinkpad)
|
if (pad != active_sinkpad)
|
||||||
goto ignore;
|
goto ignore;
|
||||||
|
|
||||||
|
gst_stream_selector_push_pending_stop (sel);
|
||||||
|
|
||||||
/* if we have a pending segment, push it out now */
|
/* if we have a pending segment, push it out now */
|
||||||
if (selpad->segment_pending) {
|
if (selpad->segment_pending) {
|
||||||
gst_pad_push_event (sel->srcpad, gst_event_new_new_segment_full (FALSE,
|
gst_pad_push_event (sel->srcpad, gst_event_new_new_segment_full (FALSE,
|
||||||
|
@ -504,6 +507,57 @@ gst_stream_selector_dispose (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_stream_selector_set_active_pad (GstStreamSelector * self,
|
||||||
|
const gchar * pad_name, GstClockTime stop_time, GstClockTime start_time)
|
||||||
|
{
|
||||||
|
GstPad *pad;
|
||||||
|
GstSelectorPad *old, *new;
|
||||||
|
GstPad **active_pad_p;
|
||||||
|
|
||||||
|
if (strcmp (pad_name, "") != 0)
|
||||||
|
pad = gst_element_get_pad (GST_ELEMENT (self), pad_name);
|
||||||
|
else
|
||||||
|
pad = NULL;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (self);
|
||||||
|
|
||||||
|
if (pad == self->active_sinkpad)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
old = GST_SELECTOR_PAD_CAST (self->active_sinkpad);
|
||||||
|
new = GST_SELECTOR_PAD_CAST (pad);
|
||||||
|
|
||||||
|
if (old && old->active && !self->pending_stop
|
||||||
|
&& GST_CLOCK_TIME_IS_VALID (stop_time)) {
|
||||||
|
/* schedule a last_stop update if one isn't already scheduled, and a
|
||||||
|
segment has been pushed before. */
|
||||||
|
memcpy (&self->pending_stop_segment, &old->segment,
|
||||||
|
sizeof (self->pending_stop_segment));
|
||||||
|
gst_segment_set_last_stop (&self->pending_stop_segment,
|
||||||
|
old->segment.format, stop_time);
|
||||||
|
self->pending_stop = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new && GST_CLOCK_TIME_IS_VALID (start_time)) {
|
||||||
|
/* schedule a new segment push */
|
||||||
|
new->segment.start = start_time;
|
||||||
|
new->segment_pending = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
active_pad_p = &self->active_sinkpad;
|
||||||
|
gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad));
|
||||||
|
GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT,
|
||||||
|
self->active_sinkpad);
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
|
if (pad)
|
||||||
|
gst_object_unref (pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_stream_selector_set_property (GObject * object, guint prop_id,
|
gst_stream_selector_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
@ -511,35 +565,10 @@ gst_stream_selector_set_property (GObject * object, guint prop_id,
|
||||||
GstStreamSelector *sel = GST_STREAM_SELECTOR (object);
|
GstStreamSelector *sel = GST_STREAM_SELECTOR (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_ACTIVE_PAD:{
|
case PROP_ACTIVE_PAD:
|
||||||
const gchar *pad_name = g_value_get_string (value);
|
gst_stream_selector_set_active_pad (sel,
|
||||||
GstPad *pad = NULL;
|
g_value_get_string (value), GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE);
|
||||||
GstPad **active_pad_p;
|
|
||||||
|
|
||||||
if (strcmp (pad_name, "") != 0)
|
|
||||||
pad = gst_element_get_pad (GST_ELEMENT (object), pad_name);
|
|
||||||
GST_OBJECT_LOCK (object);
|
|
||||||
if (pad != sel->active_sinkpad) {
|
|
||||||
GstSelectorPad *selpad;
|
|
||||||
|
|
||||||
selpad = GST_SELECTOR_PAD_CAST (pad);
|
|
||||||
/* we can only activate pads that have data received */
|
|
||||||
if (selpad && !selpad->active) {
|
|
||||||
GST_DEBUG_OBJECT (sel, "No data received on pad %" GST_PTR_FORMAT,
|
|
||||||
pad);
|
|
||||||
} else {
|
|
||||||
active_pad_p = &sel->active_sinkpad;
|
|
||||||
gst_object_replace ((GstObject **) active_pad_p,
|
|
||||||
GST_OBJECT_CAST (pad));
|
|
||||||
GST_DEBUG_OBJECT (sel, "New active pad is %" GST_PTR_FORMAT,
|
|
||||||
sel->active_sinkpad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GST_OBJECT_UNLOCK (object);
|
|
||||||
if (pad)
|
|
||||||
gst_object_unref (pad);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -741,6 +770,8 @@ block_all_pads (GstStreamSelector * self, gboolean block)
|
||||||
GstIterator *iter;
|
GstIterator *iter;
|
||||||
GstIteratorResult res;
|
GstIteratorResult res;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self->blocked != block, FALSE);
|
||||||
|
|
||||||
iter = gst_element_iterate_sink_pads (GST_ELEMENT (self));
|
iter = gst_element_iterate_sink_pads (GST_ELEMENT (self));
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -760,6 +791,7 @@ block_all_pads (GstStreamSelector * self, gboolean block)
|
||||||
done:
|
done:
|
||||||
GST_DEBUG_OBJECT (self, "block_all_pads(%d) succeeded", block);
|
GST_DEBUG_OBJECT (self, "block_all_pads(%d) succeeded", block);
|
||||||
gst_iterator_free (iter);
|
gst_iterator_free (iter);
|
||||||
|
self->blocked = block;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -768,6 +800,7 @@ error:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: blocked flag not mt-safe */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_stream_selector_block (GstStreamSelector * self)
|
gst_stream_selector_block (GstStreamSelector * self)
|
||||||
|
@ -775,11 +808,37 @@ gst_stream_selector_block (GstStreamSelector * self)
|
||||||
block_all_pads (self, TRUE);
|
block_all_pads (self, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_stream_selector_push_pending_stop (GstStreamSelector * self)
|
||||||
|
{
|
||||||
|
GstEvent *event = NULL;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (self);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (self->pending_stop)) {
|
||||||
|
GstSegment *seg = &self->pending_stop_segment;
|
||||||
|
|
||||||
|
event = gst_event_new_new_segment_full (TRUE, seg->rate,
|
||||||
|
seg->applied_rate, seg->format, seg->start, seg->last_stop, seg->time);
|
||||||
|
|
||||||
|
self->pending_stop = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
gst_pad_push_event (self->srcpad, event);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_stream_selector_switch (GstStreamSelector * self, const gchar * pad_name,
|
gst_stream_selector_switch (GstStreamSelector * self, const gchar * pad_name,
|
||||||
GstClockTime stop_time, GstClockTime start_time)
|
GstClockTime stop_time, GstClockTime start_time)
|
||||||
{
|
{
|
||||||
return;
|
g_return_if_fail (self->blocked == TRUE);
|
||||||
|
|
||||||
|
gst_stream_selector_set_active_pad (self, pad_name, stop_time, start_time);
|
||||||
|
|
||||||
|
block_all_pads (self, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -48,6 +48,10 @@ struct _GstStreamSelector {
|
||||||
guint nb_sinkpads;
|
guint nb_sinkpads;
|
||||||
|
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
|
|
||||||
|
gboolean blocked;
|
||||||
|
gboolean pending_stop;
|
||||||
|
GstSegment pending_stop_segment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstStreamSelectorClass {
|
struct _GstStreamSelectorClass {
|
||||||
|
|
Loading…
Reference in a new issue