static gboolean gst_interleave_src_event (GstPad * pad, GstEvent * event) { GstInterleave *self = GST_INTERLEAVE (gst_pad_get_parent (pad)); gboolean result; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_QOS: /* QoS might be tricky */ result = FALSE; break; case GST_EVENT_SEEK: { GstSeekFlags flags; GstSeekType curtype; gint64 cur; /* parse the seek parameters */ gst_event_parse_seek (event, &self->segment_rate, NULL, &flags, &curtype, &cur, NULL, NULL); /* check if we are flushing */ if (flags & GST_SEEK_FLAG_FLUSH) { /* make sure we accept nothing anymore and return WRONG_STATE */ gst_collect_pads_set_flushing (self->collect, TRUE); /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. */ gst_pad_push_event (self->src, gst_event_new_flush_start ()); } /* now wait for the collected to be finished and mark a new * segment */ GST_OBJECT_LOCK (self->collect); if (curtype == GST_SEEK_TYPE_SET) self->segment_position = cur; else self->segment_position = 0; self->segment_pending = TRUE; GST_OBJECT_UNLOCK (self->collect); result = forward_event (self, event); break; } case GST_EVENT_NAVIGATION: /* navigation is rather pointless. */ result = FALSE; break; default: /* just forward the rest for now */ result = forward_event (self, event); break; } gst_object_unref (self); return result; }
static gboolean gst_frei0r_mixer_src_event (GstPad * pad, GstEvent * event) { GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); gboolean ret = FALSE; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_QOS: /* QoS might be tricky */ ret = FALSE; break; case GST_EVENT_SEEK: { GstSeekFlags flags; /* parse the seek parameters */ gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL); /* check if we are flushing */ if (flags & GST_SEEK_FLAG_FLUSH) { /* make sure we accept nothing anymore and return WRONG_STATE */ gst_collect_pads_set_flushing (self->collect, TRUE); /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. */ gst_pad_push_event (self->src, gst_event_new_flush_start ()); } ret = forward_event (self, event); break; } case GST_EVENT_NAVIGATION: /* navigation is rather pointless. */ ret = FALSE; break; default: /* just forward the rest for now */ ret = forward_event (self, event); break; } gst_object_unref (self); return ret; }
static gboolean gst_frei0r_mixer_src_event (GstPad * pad, GstObject * object, GstEvent * event) { GstFrei0rMixer *self = GST_FREI0R_MIXER (object); gboolean ret = FALSE; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_QOS: /* QoS might be tricky */ ret = FALSE; break; case GST_EVENT_SEEK: { GstSeekFlags flags; /* parse the seek parameters */ gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL); /* check if we are flushing */ if (flags & GST_SEEK_FLAG_FLUSH) { /* make sure we accept nothing anymore and return WRONG_STATE */ gst_collect_pads_set_flushing (self->collect, TRUE); /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. */ gst_pad_push_event (self->src, gst_event_new_flush_start ()); } ret = gst_pad_event_default (pad, GST_OBJECT (self), event); break; } default: ret = gst_pad_event_default (pad, GST_OBJECT (self), event); break; } return ret; }
static gboolean gst_adder_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstAdder *adder; gboolean result; adder = GST_ADDER (parent); GST_DEBUG_OBJECT (pad, "Got %s event on src pad", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { GstSeekFlags flags; gdouble rate; GstSeekType start_type, stop_type; gint64 start, stop; GstFormat seek_format, dest_format; gboolean flush; /* parse the seek parameters */ gst_event_parse_seek (event, &rate, &seek_format, &flags, &start_type, &start, &stop_type, &stop); if ((start_type != GST_SEEK_TYPE_NONE) && (start_type != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (adder, "seeking failed, unhandled seek type for start: %d", start_type); goto done; } if ((stop_type != GST_SEEK_TYPE_NONE) && (stop_type != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (adder, "seeking failed, unhandled seek type for end: %d", stop_type); goto done; } dest_format = adder->segment.format; if (seek_format != dest_format) { result = FALSE; GST_DEBUG_OBJECT (adder, "seeking failed, unhandled seek format: %d", seek_format); goto done; } flush = (flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH; /* check if we are flushing */ if (flush) { /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. * Make sure we accept nothing anymore and return WRONG_STATE. * We send a flush-start before, to ensure no streaming is done * as we need to take the stream lock. */ gst_pad_push_event (adder->srcpad, gst_event_new_flush_start ()); gst_collect_pads_set_flushing (adder->collect, TRUE); /* We can't send FLUSH_STOP here since upstream could start pushing data * after we unlock adder->collect. * We set flush_stop_pending to TRUE instead and send FLUSH_STOP after * forwarding the seek upstream or from gst_adder_collected, * whichever happens first. */ GST_COLLECT_PADS_STREAM_LOCK (adder->collect); adder->flush_stop_pending = TRUE; GST_COLLECT_PADS_STREAM_UNLOCK (adder->collect); GST_DEBUG_OBJECT (adder, "mark pending flush stop event"); } GST_DEBUG_OBJECT (adder, "handling seek event: %" GST_PTR_FORMAT, event); /* now wait for the collected to be finished and mark a new * segment. After we have the lock, no collect function is running and no * new collect function will be called for as long as we're flushing. */ GST_COLLECT_PADS_STREAM_LOCK (adder->collect); /* clip position and update our segment */ if (adder->segment.stop != -1) { adder->segment.position = adder->segment.stop; } gst_segment_do_seek (&adder->segment, rate, seek_format, flags, start_type, start, stop_type, stop, NULL); if (flush) { /* Yes, we need to call _set_flushing again *WHEN* the streaming threads * have stopped so that the cookie gets properly updated. */ gst_collect_pads_set_flushing (adder->collect, TRUE); } GST_COLLECT_PADS_STREAM_UNLOCK (adder->collect); GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT, event); GST_DEBUG_OBJECT (adder, "updated segment: %" GST_SEGMENT_FORMAT, &adder->segment); /* we're forwarding seek to all upstream peers and wait for one to reply * with a newsegment-event before we send a newsegment-event downstream */ g_atomic_int_set (&adder->new_segment_pending, TRUE); result = forward_event (adder, event, flush); if (!result) { /* seek failed. maybe source is a live source. */ GST_DEBUG_OBJECT (adder, "seeking failed"); } if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending, TRUE, FALSE)) { GST_DEBUG_OBJECT (adder, "pending flush stop"); if (!gst_pad_push_event (adder->srcpad, gst_event_new_flush_stop (TRUE))) { GST_WARNING_OBJECT (adder, "Sending flush stop event failed"); } } break; } case GST_EVENT_QOS: /* QoS might be tricky */ result = FALSE; gst_event_unref (event); break; case GST_EVENT_NAVIGATION: /* navigation is rather pointless. */ result = FALSE; gst_event_unref (event); break; default: /* just forward the rest for now */ GST_DEBUG_OBJECT (adder, "forward unhandled event: %s", GST_EVENT_TYPE_NAME (event)); result = forward_event (adder, event, FALSE); break; } done: return result; }
static gboolean gst_adder_src_event (GstPad * pad, GstEvent * event) { GstAdder *adder; gboolean result; adder = GST_ADDER (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { GstSeekFlags flags; GstSeekType curtype, endtype; gint64 cur, end; gboolean flush; /* parse the seek parameters */ gst_event_parse_seek (event, &adder->segment_rate, NULL, &flags, &curtype, &cur, &endtype, &end); if ((curtype != GST_SEEK_TYPE_NONE) && (curtype != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (adder, "seeking failed, unhandled seek type for start: %d", curtype); goto done; } if ((endtype != GST_SEEK_TYPE_NONE) && (endtype != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (adder, "seeking failed, unhandled seek type for end: %d", endtype); goto done; } flush = (flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH; /* check if we are flushing */ if (flush) { /* make sure we accept nothing anymore and return WRONG_STATE */ gst_collect_pads_set_flushing (adder->collect, TRUE); /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. */ gst_pad_push_event (adder->srcpad, gst_event_new_flush_start ()); /* We can't send FLUSH_STOP here since upstream could start pushing data * after we unlock adder->collect. * We set flush_stop_pending to TRUE instead and send FLUSH_STOP after * forwarding the seek upstream or from gst_adder_collected, * whichever happens first. */ adder->flush_stop_pending = TRUE; } GST_DEBUG_OBJECT (adder, "handling seek event: %" GST_PTR_FORMAT, event); /* now wait for the collected to be finished and mark a new * segment. After we have the lock, no collect function is running and no * new collect function will be called for as long as we're flushing. */ GST_OBJECT_LOCK (adder->collect); if (curtype == GST_SEEK_TYPE_SET) adder->segment_start = cur; else adder->segment_start = 0; if (endtype == GST_SEEK_TYPE_SET) adder->segment_end = end; else adder->segment_end = GST_CLOCK_TIME_NONE; /* make sure we push a new segment, to inform about new basetime * see FIXME in gst_adder_collected() */ adder->segment_pending = TRUE; if (flush) { /* Yes, we need to call _set_flushing again *WHEN* the streaming threads * have stopped so that the cookie gets properly updated. */ gst_collect_pads_set_flushing (adder->collect, TRUE); } GST_OBJECT_UNLOCK (adder->collect); GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT, event); result = forward_event (adder, event, flush); if (!result) { /* seek failed. maybe source is a live source. */ GST_DEBUG_OBJECT (adder, "seeking failed"); } if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending, TRUE, FALSE)) { GST_DEBUG_OBJECT (adder, "pending flush stop"); gst_pad_push_event (adder->srcpad, gst_event_new_flush_stop ()); } break; } case GST_EVENT_QOS: /* QoS might be tricky */ result = FALSE; break; case GST_EVENT_NAVIGATION: /* navigation is rather pointless. */ result = FALSE; break; default: /* just forward the rest for now */ GST_DEBUG_OBJECT (adder, "forward unhandled event: %s", GST_EVENT_TYPE_NAME (event)); result = forward_event (adder, event, FALSE); break; } done: gst_object_unref (adder); return result; }