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);
}
Beispiel #3
0
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;
  }
}