static gboolean gst_rnd_buffer_size_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active) { gboolean res; GstRndBufferSize *self = GST_RND_BUFFER_SIZE (parent); switch (mode) { case GST_PAD_MODE_PULL: if (active) { GST_INFO_OBJECT (self, "starting pull"); res = gst_pad_start_task (pad, (GstTaskFunction) gst_rnd_buffer_size_loop, self, NULL); self->need_newsegment = TRUE; } else { GST_INFO_OBJECT (self, "stopping pull"); res = gst_pad_stop_task (pad); } break; case GST_PAD_MODE_PUSH: GST_INFO_OBJECT (self, "%sactivating in push mode", (active) ? "" : "de"); res = TRUE; break; default: res = FALSE; break; } return res; }
static void gst_rnd_buffer_size_finalize (GObject * object) { GstRndBufferSize *self = GST_RND_BUFFER_SIZE (object); if (self->rand) { g_rand_free (self->rand); self->rand = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
static gboolean gst_rnd_buffer_size_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstRndBufferSize *self; GstSeekType start_type; GstSeekFlags flags; GstFormat format; gint64 start; if (GST_EVENT_TYPE (event) != GST_EVENT_SEEK) { GST_WARNING_OBJECT (pad, "dropping %s event", GST_EVENT_TYPE_NAME (event)); return FALSE; } self = GST_RND_BUFFER_SIZE (parent); gst_event_parse_seek (event, NULL, &format, &flags, &start_type, &start, NULL, NULL); if (format != GST_FORMAT_BYTES) { GST_WARNING_OBJECT (pad, "only BYTE format supported"); return FALSE; } if (start_type != GST_SEEK_TYPE_SET) { GST_WARNING_OBJECT (pad, "only SEEK_TYPE_SET supported"); return FALSE; } if ((flags & GST_SEEK_FLAG_FLUSH)) { gst_pad_push_event (self->srcpad, gst_event_new_flush_start ()); gst_pad_push_event (self->sinkpad, gst_event_new_flush_start ()); } else { gst_pad_pause_task (self->sinkpad); } GST_PAD_STREAM_LOCK (self->sinkpad); if ((flags & GST_SEEK_FLAG_FLUSH)) { gst_pad_push_event (self->srcpad, gst_event_new_flush_stop (TRUE)); gst_pad_push_event (self->sinkpad, gst_event_new_flush_stop (TRUE)); } GST_INFO_OBJECT (pad, "seeking to offset %" G_GINT64_FORMAT, start); self->offset = start; self->need_newsegment = TRUE; gst_pad_start_task (self->sinkpad, (GstTaskFunction) gst_rnd_buffer_size_loop, self); GST_PAD_STREAM_UNLOCK (self->sinkpad); return TRUE; }
static gboolean gst_rnd_buffer_size_activate_pull (GstPad * pad, gboolean active) { GstRndBufferSize *self = GST_RND_BUFFER_SIZE (GST_OBJECT_PARENT (pad)); if (active) { GST_INFO_OBJECT (self, "starting pull"); return gst_pad_start_task (pad, (GstTaskFunction) gst_rnd_buffer_size_loop, self); } else { GST_INFO_OBJECT (self, "stopping pull"); return gst_pad_stop_task (pad); } }
static GstStateChangeReturn gst_rnd_buffer_size_change_state (GstElement * element, GstStateChange transition) { GstRndBufferSize *self = GST_RND_BUFFER_SIZE (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: self->offset = 0; if (!self->rand) { self->rand = g_rand_new_with_seed (self->seed); } break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: if (self->rand) { g_rand_free (self->rand); self->rand = NULL; } break; case GST_STATE_CHANGE_READY_TO_NULL: if (self->adapter) { g_object_unref (self->adapter); self->adapter = NULL; } break; default: break; } return ret; }
static GstFlowReturn gst_rnd_buffer_size_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstRndBufferSize *rnd = GST_RND_BUFFER_SIZE (parent); GstFlowReturn flow; if (rnd->adapter == NULL) rnd->adapter = gst_adapter_new (); gst_adapter_push (rnd->adapter, buf); flow = gst_rnd_buffer_size_drain_adapter (rnd, FALSE); if (flow != GST_FLOW_OK) GST_INFO_OBJECT (rnd, "flow: %s", gst_flow_get_name (flow)); return flow; }
static gboolean gst_rnd_buffer_size_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstRndBufferSize *rnd = GST_RND_BUFFER_SIZE (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: gst_rnd_buffer_size_drain_adapter (rnd, TRUE); break; case GST_EVENT_FLUSH_STOP: if (rnd->adapter != NULL) gst_adapter_clear (rnd->adapter); break; default: break; } return gst_pad_event_default (pad, parent, event); }
static void gst_rnd_buffer_size_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRndBufferSize *self = GST_RND_BUFFER_SIZE (object); switch (prop_id) { case PROP_SEED: g_value_set_uint (value, self->seed); break; case PROP_MINIMUM: g_value_set_int (value, self->min); break; case PROP_MAXIMUM: g_value_set_int (value, self->max); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }